Статус: Новичок
Группы: Участники
Зарегистрирован: 20.01.2015(UTC) Сообщений: 2
|
Здравствуйте. У меня вопрос. Я использую jcp-2.0.37886. Пытаюсь подписать soap: Код:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:esp="http://schemas.itopcase.ru/rul/esped">
<env:Header/>
<env:Body>
<esp:CheckPermission>
<esp:request>
<esp:DocumentId>580670a9-9bc9-4c62-b3e6-78ac9942b782</esp:DocumentId>
<esp:OrganizationFromSign>
<esp:Inn>123456789456</esp:Inn>
<esp:Ogrn>1234567894561</esp:Ogrn>
</esp:OrganizationFromSign>
<esp:PermissionDate>2013-08-28T15:11:00</esp:PermissionDate>
<esp:RequestClient>test</esp:RequestClient>
<esp:SignerOrganizations>
<esp:InnOgrn>
<esp:Inn>123456789456</esp:Inn>
<esp:Ogrn>1234567894561</esp:Ogrn>
</esp:InnOgrn>
</esp:SignerOrganizations>
<esp:Snils>112-115-122 05</esp:Snils>
</esp:request>
</esp:CheckPermission>
</env:Body>
</env:Envelope>
Следующим способом: Код:
public void signSOAPSMEV(SOAPMessage message) throws Exception {
/*** Инициализация ***/
// Инициализация Transforms алгоритмов.
com.sun.org.apache.xml.internal.security.Init.init();
// Инициализация JCP XML провайдера.
if(!JCPXMLDSigInit.isInitialized()) {
JCPXMLDSigInit.init();
}
// Инициализация ключевого контейнера.
KeyStore keyStore = KeyStore.getInstance(JCP.HD_STORE_NAME);
keyStore.load(null, pinCode.toCharArray());
PrivateKey privateKey = (PrivateKey) keyStore.getKey(containerName,pinCode.toCharArray());
// Сертификат открытого ключа
X509Certificate cert = (X509Certificate) keyStore.getCertificate(containerName);
/*** Подготовка документа ***/
message.getSOAPPart().getEnvelope().addNamespaceDeclaration("wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
message.getSOAPPart().getEnvelope().addNamespaceDeclaration("wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
message.getSOAPPart().getEnvelope().addNamespaceDeclaration("ds","http://www.w3.org/2000/09/xmldsig#");
message.getSOAPBody().setAttributeNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
"wsu:Id", "body");
if (message == null)
return;
// Формируем заголовок.
WSSecHeader header = new WSSecHeader();
header.setActor("http://smev.gosuslugi.ru/actors/smev");
header.setMustUnderstand(false);
// Получаем документ.
Document doc = message.getSOAPPart().getEnvelope().getOwnerDocument();
Element secHeader = header.insertSecurityHeader(message.getSOAPPart().getEnvelope().getOwnerDocument());
Element token = header.getSecurityHeader();
NodeList list = secHeader.getElementsByTagName("wsse:BinarySecurityToken");
Element binSecToken = null;
if (list.getLength()!=0){
binSecToken = (Element) list.item(0);
}else{
binSecToken = (Element) header.getSecurityHeader().appendChild(doc.createElementNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","wsse:BinarySecurityToken"));
}
binSecToken.setAttribute("wsu:Id", "SenderCertificate");
binSecToken.setAttribute(
"EncodingType",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
binSecToken.setAttribute(
"ValueType",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
/*** Подпись данных ***/
// Загрузка провайдера.
Provider xmlDSigProvider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
// Преобразования над документом.
final Transforms transforms = new Transforms(doc);
transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", xmlDSigProvider);
// Преобразования над блоком SignedInfo
List<Transform> transformList = new ArrayList<Transform>();
Transform transformC14N = fac.newTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, (XMLStructure) null);
transformList.add(transformC14N);
// Ссылка на подписываемые данные.
Reference ref = fac.newReference("#body",
fac.newDigestMethod("http://www.w3.org/2001/04/xmldsig-more#gostr3411", null),
transformList, null, null);
// Блок SignedInfo.
SignedInfo si = fac.newSignedInfo( fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411", null),
Collections.singletonList(ref));
// Блок KeyInfo.
KeyInfoFactory kif = fac.getKeyInfoFactory();
X509Data x509d = kif.newX509Data(Collections.singletonList(cert));
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(x509d));
// Подпись данных.
javax.xml.crypto.dsig.XMLSignature sig = fac.newXMLSignature(si, ki);
DOMSignContext signContext = new DOMSignContext(privateKey, token);
sig.sign(signContext);
// Блок подписи Signature.
Element sigE = (Element) XPathAPI.selectSingleNode(signContext.getParent(), "//ds:Signature");
// Блок данных KeyInfo.
Node keyE = XPathAPI.selectSingleNode(sigE, "//ds:KeyInfo", sigE);
// Элемент SenderCertificate, который должен содержать сертификат.
list = secHeader.getElementsByTagName("wsse:BinarySecurityToken");
Element cerVal = (Element)list.item(0);
//Element cerVal = (Element) XPathAPI.selectSingleNode(token, "//*[@wsu:Id='SenderCertificate']");
cerVal.setTextContent(XPathAPI.selectSingleNode(keyE, "//ds:X509Certificate", keyE).getFirstChild().getNodeValue());
// Удаляем элементы KeyInfo, попавшие в тело документа. Они должны быть только в header.
keyE.removeChild(XPathAPI.selectSingleNode(keyE, "//ds:X509Data", keyE));
NodeList chl = keyE.getChildNodes();
for (int i = 0; i < chl.getLength(); i++) {
keyE.removeChild(chl.item(i));
}
// Блок KeyInfo содержит указание на проверку подписи с помощью сертификата SenderCertificate.
Node str = keyE.appendChild(doc.createElementNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"wsse:SecurityTokenReference"));
Element strRef = (Element)str.appendChild(doc.createElementNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"wsse:Reference"));
strRef.setAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
strRef.setAttribute("URI", "#SenderCertificate");
header.getSecurityHeader().appendChild(sigE);
}
В момент подписи, как я понимаю, я должен указать ссылку на элемент, который я хочу подписать: Код:
Reference ref = fac.newReference("#body",
fac.newDigestMethod("http://www.w3.org/2001/04/xmldsig-more#gostr3411", null),
transformList, null, null);
Т.е. в данном случае, ссылка на элемент с id body, но в момент подписи выскакивает excpetion : javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID body Вот кстати как выглядит soap, перед вызовом sig.sign(signContext), на нем все и валится, видно, что id такой существует Код:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:esp="http://schemas.itopcase.ru/rul/esped" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" env:actor="http://smev.gosuslugi.ru/actors/smev">
<wsse:BinarySecurityToken wsu:Id="SenderCertificate" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:Security>
</env:Header>
<env:Body wsu:Id="body">
<esp:CheckPermission>
<esp:request>
<esp:DocumentId>580670a9-9bc9-4c62-b3e6-78ac9942b782</esp:DocumentId>
<esp:OrganizationFromSign>
<esp:Inn>123456789456</esp:Inn>
<esp:Ogrn>1234567894561</esp:Ogrn>
</esp:OrganizationFromSign>
<esp:PermissionDate>2013-08-28T15:11:00</esp:PermissionDate>
<esp:RequestClient>test</esp:RequestClient>
<esp:SignerOrganizations>
<esp:InnOgrn>
<esp:Inn>123456789456</esp:Inn>
<esp:Ogrn>1234567894561</esp:Ogrn>
</esp:InnOgrn>
</esp:SignerOrganizations>
<esp:Snils>112-115-122 05</esp:Snils>
</esp:request>
</esp:CheckPermission>
</env:Body>
</env:Envelope>
|