Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline komeks  
#1 Оставлено : 27 февраля 2013 г. 13:35:05(UTC)
komeks

Статус: Участник

Группы: Участники
Зарегистрирован: 27.02.2013(UTC)
Сообщений: 12
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Добрый день.

Столкнулся с трудностью подписать обычную XML (не соап запрос в СМЭВ). Все темы на форуме посвящены созданию подписи для СМЭВа (у нас в системе это уже реализовано).

У меня вопрос, можно ли подписать любой файл XML используя КриптоПро.
Если кто уже сталкивался с подобными проблемами прошу помочь. Прилагаю код текущей программы (не работает).

Код:

		inSOAPFile = "C:/2.xml";
		com.sun.org.apache.xml.internal.security.Init.init();
		SpecUtility.initJCP();
		KeyStore keyStore = KeyStore.getInstance(JCP.HD_STORE_NAME);
		keyStore.load(null, null);
		System.out.println("Sign cert name - " + SpecUtility.DEFAULT_ALIAS);
		PrivateKey privateKey = (PrivateKey)keyStore.getKey(SpecUtility.DEFAULT_ALIAS, SpecUtility.DEFAULT_PASSWORD);
		X509Certificate cert = (X509Certificate) keyStore.getCertificate(SpecUtility.DEFAULT_ALIAS);
		MessageFactory mf = MessageFactory.newInstance();
		//этот кусок кода от взят из СОАП подписи, что бы не переделывать
		SOAPMessage sm = mf.createMessage();
		SOAPPart soapPart = sm.getSOAPPart();
		FileInputStream is = new FileInputStream(inSOAPFile);
		soapPart.setContent(new StreamSource(is)); 
	    Source src = sm.getSOAPPart().getContent();  
	    TransformerFactory tf = TransformerFactory.newInstance();  
	    Transformer transformer = tf.newTransformer();  
	    DOMResult result = new DOMResult();  
	    transformer.transform(src, result);  
	    Document doc = (Document)result.getNode();  
	    Element SOAP_FinalPayment = doc.getDocumentElement();
	    Element token = SOAP_FinalPayment;	    
    
		Provider xmlDSigProvider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
	    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", xmlDSigProvider);
	    List<Transform> transformList = new ArrayList<Transform>();
	    Transform transform = fac.newTransform(Transform.ENVELOPED, (XMLStructure) null);
	    Transform transformC14N = fac.newTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, (XMLStructure) null);
	    transformList.add(transform);
	    transformList.add(transformC14N);
	    Reference ref = fac.newReference("#mkgu", 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));

	    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);
	    signContext.putNamespacePrefix(javax.xml.crypto.dsig.XMLSignature.XMLNS, "ds");
	    sig.sign(signContext);
	    //Тут вылетает ошибка, дальше код не успел проверить и переделать. Не обращайте на него внимание.
	    Element sigE = (Element) XPathAPI.selectSingleNode(sm.getSOAPBody(), "//ds:Signature");
	    Node keyE = XPathAPI.selectSingleNode(sigE, "//ds:KeyInfo", sigE);
	    String xpat = XPathAPI.selectSingleNode(keyE, "//ds:X509Certificate", keyE).getFirstChild().getNodeValue();
	    Text diget = doc.createTextNode(xpat);
	    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));
	    }
	    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", "#CertId");
	    SOAP_FinalPayment.appendChild(sigE);
	    
	    String mes = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
	    System.out.println(mes);



В ответ получаю ошибку Cannot resolve element with ID mkgu

Содержание XML
<?xml version="1.0" encoding="UTF-8"?>
<mkgu:body id="mkgu" xmlns:mkgu="http://vashkontrol.ru#" 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#" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" >
<mkgu:vendor id="[идентификатор вендора]">
<mkgu:formVersion>[версия опросного модуля]</mkgu:formVersion>
<mkgu:pocket>[foreign_id]</mkgu:pocket>
</mkgu:vendor>
<mkgu:forms>
...
</mkgu:form>
</mkgu:forms>
</mkgu:body>

Отредактировано пользователем 27 февраля 2013 г. 13:37:13(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#2 Оставлено : 27 февраля 2013 г. 21:17:37(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,928
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 693 раз в 654 постах
Здравствуйте.
Попробуйте явно задать:
Код:

...
DOMSignContext signContext = new DOMSignContext(privateKey, token);
signContext.setIdAttributeNS((Element) nodeToSign, <namespace>, "id");
...
sig.sign(signContext);
...

где nodeToSign - узел для подписи, содержащий атрибут id (видимо, mkgu:body).

Отредактировано пользователем 27 февраля 2013 г. 21:18:13(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
komeks оставлено 28.02.2013(UTC)
Offline komeks  
#3 Оставлено : 28 февраля 2013 г. 10:11:13(UTC)
komeks

Статус: Участник

Группы: Участники
Зарегистрирован: 27.02.2013(UTC)
Сообщений: 12
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Спасибо, помогло.

Выкладываю финальную версию рабочего алгоритма:

Код:

		System.out.println("Signed algoritm - "+alg);
		com.sun.org.apache.xml.internal.security.Init.init();
		SpecUtility.initJCP();
		KeyStore keyStore = KeyStore.getInstance(JCP.HD_STORE_NAME);
		keyStore.load(null, null);
		System.out.println("Sign cert name - " + SpecUtility.DEFAULT_ALIAS);
		PrivateKey privateKey = (PrivateKey)keyStore.getKey(SpecUtility.DEFAULT_ALIAS, SpecUtility.DEFAULT_PASSWORD);
		X509Certificate cert = (X509Certificate) keyStore.getCertificate(SpecUtility.DEFAULT_ALIAS);
	    DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
	    f.setValidating(false);
	    DocumentBuilder builder = f.newDocumentBuilder();
	    Document doc = builder.parse(new File(inSOAPFile));
	    Element token = doc.getDocumentElement();
	    token = (Element)doc.getElementsByTagName("mkgu:body").item(0);
	    System.out.println(org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc));
		Provider xmlDSigProvider = new ru.CryptoPro.JCPxml.dsig.internal.dom.XMLDSigRI();
	    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", xmlDSigProvider);
	    List<Transform> transformList = new ArrayList<Transform>();
	    Transform transform = fac.newTransform(Transform.ENVELOPED, (XMLStructure) null);
	    Transform transformC14N = fac.newTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, (XMLStructure) null);
	    transformList.add(transform);
	    transformList.add(transformC14N);
	    Reference ref = fac.newReference("#mkgu", 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));
	    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);
	    signContext.putNamespacePrefix(XMLSignature.XMLNS, "ds");
	    signContext.setIdAttributeNS(token, null, "id");
	    signContext.putNamespacePrefix(javax.xml.crypto.dsig.XMLSignature.XMLNS, "ds");
	    sig.sign(signContext);
	    System.out.println(org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc));
	    System.out.println("----");
	    Element sigE = (Element) token.getElementsByTagName("ds:Signature").item(0);
	    Node keyE = XPathAPI.selectSingleNode(sigE, "//ds:KeyInfo", sigE);	    
	    String xpat = XPathAPI.selectSingleNode(keyE, "//ds:X509Certificate", keyE).getFirstChild().getNodeValue();
	    Text diget = doc.createTextNode(xpat);
	    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));
	    }
	    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", "#CertId");
	    doc.getDocumentElement().appendChild(sigE);
	    String mes = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
	    System.out.println(mes);
	    Array.writeFile(inSOAPFile + ".signed.text.xml", mes.getBytes("UTF-8"));

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.