Пытаюсь подписать тестовое сообщение в ГИС ЖКХ (СИТ)
KриптоПро CPS 3.9, JCP 2.0, Java8, Windows7
----------------------------------------------- Файл SignCommand.java (begin) -----------------------------------------------
package ru.gosuslugi.dom.signature.demo.commands;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
//import org.apache.commons.io.FileUtils;
//import org.apache.commons.lang.StringUtils;
import kmh.gis.gkh.util.SSLSocketFactoryGisGkh;
import ru.CryptoPro.JCP.KeyStore.JCPPrivateKeyEntry;
import ru.CryptoPro.JCPxml.xmldsig.JCPXMLDSigInit;
//import ru.CryptoPro.XAdES.XAdESSignerBES;
//import ru.gosuslugi.dom.signature.demo.args.SignParameters;
import ru.gosuslugi.dom.signature.demo.exceptions.ElementNotFoundException;
import ru.gosuslugi.dom.signature.demo.xades.Consts;
import ru.gosuslugi.dom.signature.demo.xades.production.CustomizableXadesBesSigningProfileFactory;
import ru.gosuslugi.dom.signature.demo.xades.providers.CustomizableAlgorithmProvider;
import ru.gosuslugi.dom.signature.demo.xades.providers.CustomizableMessageDigestEngineProvider;
import ru.gosuslugi.dom.signature.demo.xml.IdResolver;
import ru.gosuslugi.dom.signature.demo.xml.XMLParser;
import ru.gosuslugi.dom.signature.demo.xml.XMLPrinter;
//import xades.util.GostXAdESUtility;
//import xades4j.UnsupportedAlgorithmException;
//import xades4j.algorithms.Algorithm;
import xades4j.algorithms.EnvelopedSignatureTransform;
import xades4j.algorithms.ExclusiveCanonicalXMLWithoutComments;
import xades4j.algorithms.GenericAlgorithm;
import xades4j.production.*;
import xades4j.properties.DataObjectDesc;
import xades4j.providers.KeyingDataProvider;
import xades4j.providers.MessageDigestEngineProvider;
import xades4j.providers.impl.DefaultAlgorithmsProviderEx;
import xades4j.providers.impl.DefaultMessageDigestProvider;
import xades4j.providers.impl.DirectKeyingDataProvider;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.KeyException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManagerFactory;
/**
* Выполняет подписание XML-документа.
*/
public class SignCommand {
public void execute() throws Exception {
// инициализируем Apache Santuario
org.apache.xml.security.Init.init();
// загружаем криптопровайдер
//CustomizableAlgorithmProvider provider = new CustomizableAlgorithmProvider();
//Provider provider = ProviderFactory.createProvider("CustomizableMessageDigestEngineProvider", null);
Provider provider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
//Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(provider);
//Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// загружаем хранилище закрытых ключей
//char[] storePassword = SSLSocketFactoryGisGkh.keyStorePassword_SGRC.toCharArray();
//char[] keyPassword = SSLSocketFactoryGisGkh.keyStorePassword_SGRC.toCharArray();
//KeyStore keyStore = KeyStore.getInstance(parameters.getStoreType(), provider);
KeyStore keyStore = KeyStore.getInstance("Aladdin Token JC 0", "JCSP");
KeyManagerFactory kf = KeyManagerFactory.getInstance("GostX509");
final char[] KEY_PASSWORD_KEY = SSLSocketFactoryGisGkh.keyStorePassword_SGRC.toCharArray();
InputStream stream = null;
keyStore.load(stream, KEY_PASSWORD_KEY);
kf.init(keyStore, KEY_PASSWORD_KEY);
/*
if (parameters.getStoreFile() != null) {
KeyStoreUtils.loadKeyStoreFromFile(keyStore, parameters.getStoreFile(), storePassword);
} else if (parameters.getStoreName() != null) {
KeyStoreUtils.loadKeyStoreByName(keyStore, parameters.getStoreName(), storePassword);
}
*/
// загружаем закрытый ключ
JCPPrivateKeyEntry keyEntry =
(JCPPrivateKeyEntry) keyStore.getEntry(
SSLSocketFactoryGisGkh.getAlias(),
new KeyStore.PasswordProtection( SSLSocketFactoryGisGkh.keyStorePassword_SGRC.toCharArray()));
//System.out.println("keyEntry.getCertificate().toString() = " + keyEntry.getCertificate().toString());
//System.out.println("keyEntry.getPrivateKey().toString() = " + keyEntry.getPrivateKey().toString());
// создаем провайдер для доступа к закрытому ключу
KeyingDataProvider kp = new DirectKeyingDataProvider((X509Certificate) keyEntry.getCertificate(), keyEntry.getPrivateKey());
// создаем провайдер, описывающий используемые алгоритмы
CustomizableAlgorithmProvider algorithmsProvider = new CustomizableAlgorithmProvider();
algorithmsProvider.setSignatureAlgorithm(Consts.SIGNATURE_ALGORITHM);
//algorithmsProvider.setSignatureAlgorithm("GOST R 34.11-94 with GOST R 34.10-2001");
algorithmsProvider.setCanonicalizationAlgorithmForSignature(Consts.CANONICALIZATION_ALGORITHM_FOR_SIGNATURE);
algorithmsProvider.setCanonicalizationAlgorithmForTimeStampProperties(Consts.CANONICALIZATION_ALGORITHM_FOR_TIMESTAMP_PROPERTIES);
algorithmsProvider.setDigestAlgorithmForDataObjsReferences(Consts.DIGEST_ALGORITHM_URI);
algorithmsProvider.setDigestAlgorithmForReferenceProperties(Consts.DIGEST_ALGORITHM_URI);
algorithmsProvider.setDigestAlgorithmForTimeStampProperties(Consts.DIGEST_ALGORITHM_URI);
// создаем провайдер, ответственный за расчет хешей
MessageDigestEngineProvider messageDigestEngineProvider = new CustomizableMessageDigestEngineProvider(Consts.DIGEST_ALGORITHM_NAME, provider);
// настраиваем профиль подписания
/*
XadesSigningProfile profile = new CustomizableXadesBesSigningProfileFactory()
.withKeyingProvider(kp)
.withAlgorithmsProvider(algorithmsProvider)
.withMessageDigestEngineProvider(messageDigestEngineProvider)
.create();
*/
XadesSigningProfile profile = new CustomizableXadesBesSigningProfileFactory()
.withKeyingProvider(kp)
.withMessageDigestEngineProvider(messageDigestEngineProvider)
/*
.withMessageDigestEngineProvider(
new DefaultMessageDigestProvider() {
@Override
public MessageDigest getEngine(String digestAlgorithmURI) throws UnsupportedAlgorithmException {
try {
return MessageDigest.getInstance("GOST3411");
} catch (NoSuchAlgorithmException nsae) {
throw new UnsupportedAlgorithmException(nsae.getMessage(), digestAlgorithmURI, nsae);
}
}
}
)
*/
.withAlgorithmsProvider( algorithmsProvider )
/*
.withAlgorithmsProvider(new DefaultAlgorithmsProviderEx(){
@Override
public Algorithm getSignatureAlgorithm(String keyAlgorithmName)
throws UnsupportedAlgorithmException {
//
return new GenericAlgorithm("http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411");
}
@Override
public String getDigestAlgorithmForReferenceProperties() {
return "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
}
})
*/
.create();
// создаем объект, ответственный за создание подписи
XadesSigner signer = profile.newSigner();
// загружаем проверяемый XML-документ
Document document = XMLParser.parseXml( new File("c://workspace_9_0//hr.xml") );
// объявляем атрибут Id в качестве идентифицирующего
IdResolver.resolveIds(document.getDocumentElement());
// ищем подписываемый элемент
String signedElementId = "sgrc123";
Element signedElement = document.getElementById(signedElementId);
if (signedElement == null) {
throw new ElementNotFoundException("Element to be signed not found: " + signedElementId);
}
// ищем элемент, в который нужно поместить подпись; если не указан, помещаем подпись в подписываемый элемент
//String containerElementId = parameters.getContainerElementId() == null ? signedElementId : parameters.getContainerElementId();
String containerElementId = signedElementId;
Element signatureContainer = document.getDocumentElement();// getElementById(containerElementId);
if (signatureContainer == null) {
throw new ElementNotFoundException("Container element not found: " + containerElementId);
}
// настраиваем подписываемые данные
DataObjectDesc obj = new DataObjectReference('#' + signedElementId);
obj.withTransform(new EnvelopedSignatureTransform());
if (containerElementId.equals(signedElementId)) {
// если подпись помещается в подписываемый элемент, применяем трансформацию enveloped signature transform
// если этого не сделать, подпись нельзя будет проверить
obj.withTransform(new EnvelopedSignatureTransform());
}
// применяем трансформацию Exclusive XML Canonicalization 1.0 without comments (комментарии исключаются из подписываемых данных)
obj.withTransform(new ExclusiveCanonicalXMLWithoutComments());
// создаем подпись
JCPXMLDSigInit.init();
SignedDataObjects dataObjs = new SignedDataObjects(obj);
signer.sign(dataObjs, signatureContainer, SignatureAppendingStrategies.AsFirstChild);
// выводим результат в stdout
System.out.println(XMLPrinter.toString(document));
// выводим результат в файл
byte[] xmlBytes = XMLPrinter.toBytes(document);
FileOutputStream fos = new FileOutputStream("c://workspace_9_0//hr_singed.xml");
fos.write(xmlBytes);
fos.flush();
fos.close();
}
}
----------------------------------------------- Файл SignCommand.java (end) -----------------------------------------------
----------------------------------------------- Файл Consts.java (begin) -----------------------------------------------
package ru.gosuslugi.dom.signature.demo.xades;
/**
* Имена используемых алгоритмов.
*/
public class Consts {
private Consts() {
}
/**
* Алгоритм электронной подписи
*/
public static final String SIGNATURE_ALGORITHM = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
/**
* Алгоритм каноникализации для подписи
*/
public static final String CANONICALIZATION_ALGORITHM_FOR_SIGNATURE = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
/**
* Алгоритм каноникализации для штампа времени
*/
public static final String CANONICALIZATION_ALGORITHM_FOR_TIMESTAMP_PROPERTIES = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
/**
* Алгоритм расчета хешей. Используется в XML-документе.
*/
public static final String DIGEST_ALGORITHM_URI = "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
/**
* Алгоритм расчета хешей. Используется для создания экземпляра алгоритма.
*/
public static final String DIGEST_ALGORITHM_NAME = "GOST3411";
/**
* Ссылка на блок {@code <xades:SignedSignatureProperties>}
*/
public static final String SIGNED_PROPS_TYPE_URI = "http://uri.etsi.org/01903#SignedProperties";
}
----------------------------------------------- Файл Consts.java (end) -----------------------------------------------
----------------------------------------------- Получаю ошибку:
xades4j.XAdES4jXMLSigException: The requested algorithm
http://www.w3.org/2001/0...#gostr34102001-gostr3411 does not exist. Original Message was: null
at xades4j.production.SignerBES.createSignature(SignerBES.java:313)
at xades4j.production.SignerBES.sign(SignerBES.java:159)
at ru.gosuslugi.dom.signature.demo.commands.SignCommand.execute(SignCommand.java:212)
at ru.gosuslugi.dom.schema.integration._8_6_0_4.house_management_service.SOAPSecurityHandler.handleMessage(SOAPSecurityHandler.java:89)
at ru.gosuslugi.dom.schema.integration._8_6_0_4.house_management_service.SOAPSecurityHandler.handleMessage(SOAPSecurityHandler.java:1)
at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandleMessage(HandlerProcessor.java:282)
at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandlersRequest(HandlerProcessor.java:123)
at com.sun.xml.internal.ws.handler.ClientSOAPHandlerTube.callHandlersOnRequest(ClientSOAPHandlerTube.java:127)
at com.sun.xml.internal.ws.handler.HandlerTube.processRequest(HandlerTube.java:112)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862)
at com.sun.xml.internal.ws.client.Stub.process(Stub.java:448)
at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:178)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
at com.sun.proxy.$Proxy41.exportHouseData(Unknown Source)
at ru.gosuslugi.dom.schema.integration._8_6_0_4.house_management_service.clientsample.ClientSample.main(ClientSample.java:118)
Caused by: org.apache.xml.security.signature.XMLSignatureException: The requested algorithm
http://www.w3.org/2001/0...#gostr34102001-gostr3411 does not exist.
Original Message was: null
Original Exception was java.lang.NullPointerException
at org.apache.xml.security.algorithms.SignatureAlgorithm.getSignatureAlgorithmSpi(SignatureAlgorithm.java:160)
at org.apache.xml.security.algorithms.SignatureAlgorithm.<init>(SignatureAlgorithm.java:135)
at org.apache.xml.security.algorithms.SignatureAlgorithm.<init>(SignatureAlgorithm.java:106)
at org.apache.xml.security.signature.SignedInfo.<init>(SignedInfo.java:141)
at org.apache.xml.security.signature.XMLSignature.<init>(XMLSignature.java:301)
at xades4j.production.SignerBES.createSignature(SignerBES.java:309)
... 19 more
Client : handleFault()......
com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: EXP001000: Внутренняя ошибка Please see the server log to find more detail
regarding exact cause of the failure.
at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:124)
at com.sun.xml.internal.ws.client.sei.StubHandler.readResponse(StubHandler.java:238)
at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:189)
at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:276)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:104)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
at com.sun.proxy.$Proxy41.exportHouseData(Unknown Source)
at ru.gosuslugi.dom.schema.integration._8_6_0_4.house_management_service.clientsample.ClientSample.main(ClientSample.java:118)
---------------------------Кто нибудь может подсказать в каком направлении копать!?-------------------------------
Заранее спасибо.