Доброго дня.
Есть задача реализовать взаимодействие с СМЭВ. Для этого создано приложение на Java с использованием JCP (2.0.28830)
Получен ключевой контейнер и сертификат для тестового стенда СМЭВ. Использую эндпоинт
http://smev-mvf.test.gosuslugi.ru:7777/gateway/services/SID0004151/1.00. Сообщение подписывается без ошибок, но сервис в ответ отдает: Unauthorized request
<ns0:faultCode>ESIA-005008</ns0:faultCode>
<ns0:faultString>Unauthorized request</ns0:faultString>
подскажите, возможную причину, что делаю не так, что исправить ?
Спасибо!
Листинг приложения:
============================================================
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPMessage;
public class adpEsia {
public static void main(String[] args) throws Exception {
SOAPXMLSignatureManager sm = SOAPXMLSignatureManager.getInstance();
final SOAPMessage message;
FileInputStream is = new FileInputStream("c:\\identif.xml");
message = MessageFactory.newInstance().createMessage(new MimeHeaders(), is);
sm.signSOAPMessage(message);
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out);
String strMsg = new String(out.toByteArray(), "utf-8");
System.out.println(strMsg);
}
}
====================================================
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerException;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.token.X509Security;
import org.apache.xml.security.transforms.TransformationException;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class SOAPXMLSignatureManager {
private static final String PASSWORD = "1234567890";
private static final String ALIAS = "RaUser-913a59f4-cbd5-46fb-899e-325cb8030d21";
private Provider xmlDSigProvider;
private KeyStore keyStore;
private PrivateKey privateKey;
private X509Certificate cert;
private static SOAPXMLSignatureManager instance;
public static synchronized SOAPXMLSignatureManager getInstance(){
if (instance == null){
instance = new SOAPXMLSignatureManager();
}
return instance;
}
private SOAPXMLSignatureManager() {
org.apache.xml.security.Init.init();
xmlDSigProvider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
try {
keyStore = KeyStore.getInstance("HDImageStore");
keyStore.load(null, null);
privateKey = (PrivateKey)keyStore.getKey(ALIAS, PASSWORD.toCharArray());
cert = (X509Certificate)keyStore.getCertificate(ALIAS);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
}
public SOAPMessage signSOAPMessage(SOAPMessage message) throws SOAPException, WSSecurityException, TransformationException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, MarshalException, XMLSignatureException, TransformerException, IOException {
message.getSOAPPart().getEnvelope().addNamespaceDeclaration("ds", "http://www.w3.org/2000/09/xmldsig#");
Document doc = message.getSOAPPart().getEnvelope().getOwnerDocument();
//Добавляем заголовки для помещения информации о подписи:
WSSecHeader header = new WSSecHeader();
header.setActor("http://smev.gosuslugi.ru/actors/smev");
header.setMustUnderstand(false);
header.insertSecurityHeader(message.getSOAPPart().getEnvelope().getOwnerDocument());
// Элемент подписи.
Element token = header.getSecurityHeader();
//logger.info("token: {}", token);
// Загрузка провайдера.
Provider xmlDSigProvider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
//logger.info("xmlDSigProvider: {}", xmlDSigProvider);
//Добавляем описание преобразований над документом и узлом SignedInfo согласно методическим рекомендациям СМЭВ.
final Transforms transforms = new Transforms(doc);
transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", xmlDSigProvider);
//Преобразования над узлом ds:SignedInfo:
List<Transform> transformList = new ArrayList<Transform>();
Transform transformC14N = fac.newTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, (XMLStructure) null);
transformList.add(transformC14N);
// Ссылка на подписываемые данные с алгоритмом хеширования ГОСТ 34.11.
Reference ref = fac.newReference("#body", fac.newDigestMethod("http://www.w3.org/2001/04/xmldsig-more#gostr3411", null),
transformList, null, null);
//Задаём алгоритм подписи:
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));
//Создаём узел ds:KeyInfo с информацией о сертификате:
KeyInfoFactory kif = fac.getKeyInfoFactory();
X509Data x509d = kif.newX509Data(Collections.singletonList(cert));
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(x509d));
//Подписываем данные в элементе token:
javax.xml.crypto.dsig.XMLSignature sig = fac.newXMLSignature(si, ki);
DOMSignContext signContext = new DOMSignContext((Key) privateKey, token);
sig.sign(signContext);
//Следующий этап — поместить узел ds:Signature и сертификат (X509Certificate) в узел wsse:Security,
//причём сертификат нужно удалить из ds:KeyInfo и оставить там ссылку на wsse:BinarySecurityToken с сертификатом:
// Узел подписи Signature.
Element sigE = (Element) XPathAPI.selectSingleNode(signContext.getParent(), "//ds:Signature");
// Блок данных KeyInfo.
Node keyE = XPathAPI.selectSingleNode(sigE, "//ds:KeyInfo", sigE);
// Элемент SenderCertificate, который должен содержать сертификат.
Element cerVal = (Element) XPathAPI.selectSingleNode(token, "//*[@wsu:Id='SenderCertificate']");
cerVal.setTextContent(XPathAPI.selectSingleNode(keyE, "//ds:X509Certificate", keyE).getFirstChild().getNodeValue());
// Удаляем содержимое KeyInfo
keyE.removeChild(XPathAPI.selectSingleNode(keyE, "//ds:X509Data", keyE));
// logger.info("keyE:{}" , keyE.getNodeName());
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);
return message;
}
}
=============================================================================
Пример сообщения:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 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">
<env:Header>
<wsse:Security env:actor="http://smev.gosuslugi.ru/actors/smev">
<wsse:BinarySecurityToken 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" wsu:Id="SenderCertificate">MIIHHTCCBsygAwIBAgIKWYFg5QAAAAADozAIBgYqhQMCAgMwggFGMRgwFgYFKoUDZAESDTEyMzQ1
Njc4OTAxMjMxGjAYBggqhQMDgQMBARIMMDAxMjM0NTY3ODkwMSkwJwYDVQQJDCDQodGD0YnQtdCy
0YHQutC40Lkg0LLQsNC7INC0LiAyNjEXMBUGCSqGSIb3DQEJARYIY2FAcnQucnUxCzAJBgNVBAYT
AlJVMRgwFgYDVQQIDA83NyDQnNC+0YHQutCy0LAxFTATBgNVBAcMDNCc0L7RgdC60LLQsDEkMCIG
A1UECgwb0J7QkNCeINCg0L7RgdGC0LXQu9C10LrQvtC8MTAwLgYDVQQLDCfQo9C00L7RgdGC0L7Q
stC10YDRj9GO0YnQuNC5INGG0LXQvdGC0YAxNDAyBgNVBAMMK9Ci0LXRgdGC0L7QstGL0Lkg0KPQ
piDQoNCi0JogKNCg0KLQm9Cw0LHRgSkwHhcNMTYwODAxMDczNDAwWhcNMTcwODAxMDc0NDAwWjCB
zDEYMBYGBSqFA2QBEg0xMDIzMjAwMDAwMDEwMRowGAYIKoUDA4EDAQESDDAwMzIzMjAwNTQ4NDEh
MB8GA1UECB4YADcANwAgBDMALgAgBBwEPgRBBDoEMgQwMRUwEwYDVQQHHgwEHAQ+BEEEOgQyBDAx
KTAnBgNVBAoeIAQfBBAEHgAgAKsEHwQ+BEcEQgQwACAEEQQwBD0EOgC7MS8wLQYDVQQDHiYEKAQ7
BE4ENwAgBCEEHAQtBBIAIAQbBDUEQgQ+ACAEEQQwBD0EOjBjMBwGBiqFAwICEzASBgcqhQMCAiQA
BgcqhQMCAh4BA0MABEBwWziHMU+6IFR/t6rPVzhOf24C2BXDPeEgRHf2s5QUpuLf5ouArqGwgZYU
OrZPOPjcMmxb8S5MX4D296pKuOR3o4IEDzCCBAswDgYDVR0PAQH/BAQDAgTwMCYGA1UdJQQfMB0G
CCsGAQUFBwMEBgcqhQMCAiIGBggrBgEFBQcDAjAdBgNVHQ4EFgQUvZAEKBW+FLuh2rums/HK/8hl
7wMwggGHBgNVHSMEggF+MIIBeoAUQbLMMpw4fy39jIYVWCNiCnf1LP+hggFOpIIBSjCCAUYxGDAW
BgUqhQNkARINMTIzNDU2Nzg5MDEyMzEaMBgGCCqFAwOBAwEBEgwwMDEyMzQ1Njc4OTAxKTAnBgNV
BAkMINCh0YPRidC10LLRgdC60LjQuSDQstCw0Lsg0LQuIDI2MRcwFQYJKoZIhvcNAQkBFghjYUBy
dC5ydTELMAkGA1UEBhMCUlUxGDAWBgNVBAgMDzc3INCc0L7RgdC60LLQsDEVMBMGA1UEBwwM0JzQ
vtGB0LrQstCwMSQwIgYDVQQKDBvQntCQ0J4g0KDQvtGB0YLQtdC70LXQutC+0LwxMDAuBgNVBAsM
J9Cj0LTQvtGB0YLQvtCy0LXRgNGP0Y7RidC40Lkg0YbQtdC90YLRgDE0MDIGA1UEAwwr0KLQtdGB
0YLQvtCy0YvQuSDQo9CmINCg0KLQmiAo0KDQotCb0LDQsdGBKYIQA67MaJpOeLRCL2VS7gU/gzBo
BgNVHR8EYTBfMF2gW6BZhldodHRwOi8vY2VydGVucm9sbC50ZXN0Lmdvc3VzbHVnaS5ydS9yYS9j
ZHAvNDFiMmNjMzI5YzM4N2YyZGZkOGM4NjE1NTgyMzYyMGE3N2Y1MmNmZi5jcmwwWQYIKwYBBQUH
AQEETTBLMEkGCCsGAQUFBzAChj1odHRwOi8vY2VydGVucm9sbC50ZXN0Lmdvc3VzbHVnaS5ydS9y
YS9jZHAvdGVzdF9jYV9ydGxhYnMuY2VyMDYGBSqFA2RvBC0MKyLQmtGA0LjQv9GC0L7Qn9GA0L4g
Q1NQIiAo0LLQtdGA0YHQuNGPIDMuNikwKwYDVR0QBCQwIoAPMjAxNjA4MDEwNzM0MDBagQ8yMDE3
MDgwMTA3MzQwMFowHQYDVR0gBBYwFDAIBgYqhQNkcQEwCAYGKoUDZHECMIHdBgUqhQNkcASB0zCB
0AwrItCa0YDQuNC/0YLQvtCf0YDQviBDU1AiICjQstC10YDRgdC40Y8gMy42KQxTItCj0LTQvtGB
0YLQvtCy0LXRgNGP0Y7RidC40Lkg0YbQtdC90YLRgCAi0JrRgNC40L/RgtC+0J/RgNC+INCj0KYi
INCy0LXRgNGB0LjQuCAxLjUMJeKEliDQodCkLzEyNC0yMjM4INC+0YIgMDQuMTAuMjAxMyDQsy4M
JeKEliDQodCkLzEyOC0yMzUyINC+0YIgMTUuMDQuMjAxNCDQsy4wCAYGKoUDAgIDA0EArPX8VrSj
LyOvtxN+zNTZJ2s4FkkwBuEHT2QtY849lKqKtckLgA06BmUDajj5zNYuUrdwTJbRjTTASC4eSpds
Pg==</wsse:BinarySecurityToken>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
<Reference URI="#body">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
<DigestValue>OvgEYNMg1H3z75NGvdD1k+d+GElue9dum9Tp8BSMCWU=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>V8/pRo1i+zhB3P3nKHJ81lOA1iHHQZGZqNfcmpTX3l8WrRYsENZ7/P1M5/wIYrDMVwCd1vvO9bql
yfqk2RjI5g==</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SenderCertificate" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</env:Header>
<env:Body wsu:Id="body">
<esia:Identification xmlns:esia="http://mks.esia.rstyle.ru/" xmlns="http://smev.gosuslugi.ru/rev120315">
<Message>
<Sender>
<Code>TEST00001</Code>
<Name>Шлюз СМЭВ</Name>
</Sender>
<Recipient>
<Code>ISIA01001</Code>
<Name>Electronic system identification and authentication</Name>
</Recipient>
<Originator>
<Code>TEST00001</Code>
<Name>Шлюз СМЭВ</Name>
</Originator>
<Service>
<Mnemonic>ESIARegister</Mnemonic>
<Version>1.00</Version>
</Service>
<TypeCode>OTHR</TypeCode>
<Status>REQUEST</Status>
<Date>2016-08-02T10:37:05.059+03:00</Date>
<ExchangeType>0</ExchangeType>
<CaseNumber>Test</CaseNumber>
</Message>
<MessageData>
<AppData>
<esia:passportSeries>1111</esia:passportSeries>
<esia:passportNumber>111111</esia:passportNumber>
<esia:firstname>XXXXX</esia:firstname>
<esia:lastname>XXXXXXX</esia:lastname>
<esia:middlename>XXXXXXX</esia:middlename>
<esia:mobile>+1(111)1111111</esia:mobile>
<esia:snils>111-111-111 11</esia:snils>
<esia:inn>111111111111</esia:inn>
</AppData>
</MessageData>
</esia:Identification>
</env:Body>
</env:Envelope>
==============================================================================
Отредактировано пользователем 2 августа 2016 г. 13:33:32(UTC)
| Причина: Не указана