Статус: Активный участник
Группы: Участники
Зарегистрирован: 11.09.2011(UTC) Сообщений: 37
|
Андрей * написал:Elijah написал:Доброе время суток. Есть скрипт, который подписывает XML-ку средствами CAPICOM в браузере IE (подписывает, используя CryptoPro, закрытым ключом из контейнера). Задача воспроизвести этот код на С#. Код благодаря интеграции COM в C# почти копируется (минимум изменений), но вот подписанные XML-ки отличаются. XML, подписанная JS имеет 2 сертификата (подписавшего и, как я понял, ответсвенного лица, выдавшего ключ), а подписанный C# имеет только один сертификат (подписавшего). Подскажите куда копать. Копать в сторону указания правильного флага - включить всю цепочку сертификации, а не только сертификат автора. В таких случаях обычно прикладывают участок инициализации объектов, атрибутов и создание подписи, но я просить не буду. Остается только гадать, что было указано в C# Цитата: подписанные XML-ки отличаются. XML, подписанная JS имеет 2 сертификата (подписавшего и, как я понял, ответсвенного лица, выдавшего ключ), а подписанный C# имеет только один сертификат (подписавшего).
Use CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN = 1 http://cpdn.cryptopro.ru...example_CapicomSign.htmlХотя в примерах КриптоПРО (точнее в SDK MS Capicom) Dim IncludeOption : IncludeOption = CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT - не включать корневой... Андрей, спасибо большое. Вопрос был больше общий, потому что я еще не глубоко в теме. Дело в том, что явно этот параметр нигде не инициализируется. Привожу частично код JS: Код:
xmldoc = new ActiveXObject("MSXML2.DOMDocument.5.0");
xmldoce = new ActiveXObject("MSXML2.DOMDocument.5.0");
xmldsig = new ActiveXObject("Msxml2.MXDigitalSignature.5.0");
oStore = new ActiveXObject("CAPICOM.Store.2");
oCerts = new ActiveXObject("CAPICOM.Certificates");
oSigner = new ActiveXObject("CAPICOM.Signer");
xmldoc.loadXML(document.getElementById('AAAD').value);
xmldoce.async = false;
xmldoce.validateOnParse = false;
xmldoce.preserveWhiteSpace = false;
xmldoce.resolveExternals = false;
xmldoce.loadXML("..."); //тут у нас XML-ка
elmToWrap = xmldoc.documentElement.cloneNode(true);
elmWhereTo = xmldoce.selectSingleNode("//*[@Id='" + dsigObjectId +"']");
elmWhereTo.appendChild(elmToWrap);
xmldoc = xmldoce;
xmldoce = null;
oStore.Open(STORE_LOCATION, STORE_NAME, 128);
oCerts = oStore.Certificates;
if (oCerts.Count == 0)
{
alert("нет сертификатов");
return null;
}
oSelectedCerts = oCerts.Select();
oSignerCert = oSelectedCerts(1);
xmldsig.signature = xmldoc.selectSingleNode("//*[count(ancestor::*)=0]");
pKey = xmldsig.createKeyFromCSP(oSignerCert.PrivateKey.ProviderType, oSignerCert.PrivateKey.ProviderName, oSignerCert.PrivateKey.ContainerName, 0);
pKeyOut = xmldsig.sign(pKey, 2);
На C# это выглядит почти так же. Но, видимо, где-то есть неявное различие. Код:
static CAPICOM.Certificate getCert()
{
CAPICOM.Store oStore = new CAPICOM.StoreClass();
CAPICOM.Signer oSigner = new CAPICOM.SignerClass();
oStore.Open(CAPICOM.CAPICOM_STORE_LOCATION.CAPICOM_CURRENT_USER_STORE, "My", CAPICOM.CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_EXISTING_ONLY);
foreach(CAPICOM.Certificate c in oStore.Certificates) {
return c;
}
return null;
}
MSXML2.DOMDocument50 xmldoc = new MSXML2.DOMDocument50Class();
MSXML2.DOMDocument50 xmldoce = new MSXML2.DOMDocument50Class();
MSXML2.MXDigitalSignature50 xmldsig = new MSXML2.MXDigitalSignature50Class();
xmldoc.loadXML(xml);
demand = xml;
//xmldsig = new ActiveXObject("Msxml2.MXDigitalSignature.5.0");
string dsigObjectId = "AAAAA";
//Конверт
xmldoce.async = false;
xmldoce.validateOnParse = false;
xmldoce.preserveWhiteSpace = false;
xmldoce.resolveExternals = false;
xmldoce.loadXML("...'"); //так же XML-ка, что и в JS 1 к 1
//Размещение текста в конверт
MSXML2.IXMLDOMNode elmToWrap = xmldoc.documentElement.cloneNode(true);
MSXML2.IXMLDOMNode elmWhereTo = xmldoce.selectSingleNode("//*[@Id='" + dsigObjectId + "']");
elmWhereTo.appendChild(elmToWrap);
xmldoc = xmldoce;
xmldoce = null;
CAPICOM.Certificate cert = getCert(); // в-ция выше
xmldsig.signature = xmldoc.selectSingleNode("//*[count(ancestor::*)=0]");
MSXML2.IXMLDSigKey key = xmldsig.createKeyFromCSP((int)cert.PrivateKey.ProviderType, cert.PrivateKey.ProviderName, cert.PrivateKey.ContainerName, 0);
MSXML2.IXMLDSigKey keyOut = xmldsig.sign(key, MSXML2.XMLDSIG_WRITEKEYINFO.CERTIFICATES);
В данном случае подписывает MXDigitalSignature50. Как ему сообщить этот параметр?
|