Развернуть все
Свернуть все

Создание и проверка подписи для взаимодействия со СМЭВ

Пример создания и проверки подписи документа XML с использованием шаблона документа для взаимодействия со СМЭВ

HTML
<script language="javascript" src="cadesplugin_api.js"></script>

Приведенный пример использует синхронную версию плагина. Также см. пример работы с асинхронными обьектами.

JavaScript
    var CAPICOM_CURRENT_USER_STORE = 2;
    var CAPICOM_MY_STORE = "My";
    var CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2;
    var CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1;
    var CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE = 2;
    var CADESCOM_ENCODE_BASE64 = 0;

    function GetCertificateBySubjectName(certSubjectName) {
        var oStore = cadesplugin.CreateObject("CAdESCOM.Store");
        oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE,
            CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);

        var oCertificates = oStore.Certificates.Find(
            CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME, certSubjectName);
        if (oCertificates.Count == 0) {
            alert("Certificate not found: " + certSubjectName);
            return;
        }
        var oCertificate = oCertificates.Item(1);

        return oCertificate;
    }

    function SignCreate(oCertificate, dataToSign) {

        // Создаем объект CAdESCOM.CPSigner
        var oSigner = cadesplugin.CreateObject("CAdESCOM.CPSigner");
        oSigner.Certificate = oCertificate;

        // Создаем объект CAdESCOM.SignedXML
        var oSignedXML = cadesplugin.CreateObject("CAdESCOM.SignedXML");
        oSignedXML.Content = dataToSign;

        // Указываем тип подписи - в данном случае по шаблону
        oSignedXML.SignatureType = CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE;

        var sSignedMessage = "";
        try {
            sSignedMessage = oSignedXML.Sign(oSigner);
        } catch (err) {
            alert("Failed to create signature. Error: " + cadesplugin.getLastError(err));
            return;
        }

        return sSignedMessage;
    }

    function Verify(sSignedMessage) {

        // Создаем объект CAdESCOM.SignedXML
        var oSignedXML = cadesplugin.CreateObject("CAdESCOM.SignedXML");

        try {
            oSignedXML.Verify(sSignedMessage);
        } catch (err) {
            alert("Failed to verify signature. Error: " + cadesplugin.getLastError(err));
            return false;
        }

        return true;
    }

    function run() {
        var oCertName = document.getElementById("CertName");
        var sCertName = oCertName.value; // Здесь следует заполнить SubjectName сертификата
        if ("" == sCertName) {
            alert("Введите имя сертификата (CN).");
            return;
        }

        // Ищем сертификат для подписи
        var oCertificate = GetCertificateBySubjectName(sCertName);

        // В шаблоне документа обязательно должны присутствовать следующие элементы:
        // BinarySecurityToken - сертификат ключа подписи в кодировке BASE64
        //                       атрибут Id должен содержать уникальный идентификатор
        //                       сертификата в документе
        // Signature - элемент с описанием свойств подписи:
        //     SignedInfo - информация о подписываемых элементах:
        //         CanonicalizationMethod - алгоритм приведения к каноническому виду.
        //                                  Для СМЭВ "http://www.w3.org/2001/10/xml-exc-c14n#"
        //         SignatureMethod - идентификатор алгоритма подписи.
        //                           Для СМЭВ "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"
        //         Reference - атрибут URI должен содержать ссылку на подписываемые элементы в вашем документе:
        //             Transforms - преобразования, которые следует применить к подписываемым элементам.
        //                          В примере - приведение к каноническому виду.
        //             DigestMethod - идентификатор алгоритма хэширования.
        //                            Для СМЭВ "http://www.w3.org/2001/04/xmldsig-more#gostr3411"
        //             DigestValue - Хэш-значение подписываемых элементов. Данный элемент следует оставить пустым.
        //                           Его значение будет заполнено при создании подписи.
        //     SignatureValue - значение подписи. Данный элемент следует оставить пустым.
        //                      Его значение будет заполнено при создании подписи.
        //     KeyInfo - информация о сертификате ключа подписи
        //         SecurityTokenReference - ссылка на сертификат
        //             Reference - атрибут ValueType должен содержать значение
        //                         "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
        //                         Атрибут URI должен содержать ссылку на уникальный идентификатор
        //                         сертификата (такой же, как указан в элементе BinarySecurityToken)
        var sContent =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
            "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" +
            "    <s:Header>" +
            "        <o:Security s:mustUnderstand=\"1\" xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" s:actor=\"http://smev.gosuslugi.ru/actors/smev\">" +
            "            <o:BinarySecurityToken u:Id=\"uuid-ee82d445-758b-42cb-996c-666b74b60022-2\" ValueType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3\" EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" +
            oCertificate.Export(CADESCOM_ENCODE_BASE64) +
            "            </o: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=\"#_1\">" +
            "                        <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></DigestValue>" +
            "                    </Reference>" +
            "                </SignedInfo>" +
            "                <SignatureValue></SignatureValue>" +
            "                <KeyInfo>" +
            "                    <o:SecurityTokenReference>" +
            "                    <o:Reference ValueType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3\" URI=\"#uuid-ee82d445-758b-42cb-996c-666b74b60022-2\" />" +
            "                    </o:SecurityTokenReference>" +
            "                </KeyInfo>" +
            "            </Signature>" +
            "        </o:Security>" +
            "    </s:Header>" +
            "    <s:Body u:Id=\"_1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
            "        <UnifoTransferMsg xmlns=\"http://roskazna.ru/SmevUnifoService/\">" +
            "           <Message xmlns=\"http://smev.gosuslugi.ru/rev111111\">" +
            "               <Sender>" +
            "                   <Code>RKZN00001</Code>" +
            "                   <Name>Vasya</Name>" +
            "               </Sender>" +
            "               <Recipient>" +
            "                   <Code>RKZN00001</Code>" +
            "                   <Name>Petya</Name>" +
            "               </Recipient>" +
            "               <TypeCode>GFNC</TypeCode>" +
            "               <Status>REQUEST</Status>" +
            "               <Date>2013-04-24T11:52:30.4958506+04:00</Date>" +
            "               <ExchangeType>6</ExchangeType>" +
            "           </Message>" +
            "           <MessageData xmlns=\"http://smev.gosuslugi.ru/rev111111\">" +
            "               <AppData>" +
            "                   <exportData xmlns=\"http://rosrazna.ru/xsd/SmevUnifoService\">" +
            "                       <DataRequest xmlns=\"http://roskazna.ru/xsd/PGU_DataRequest\">" +
            "                           <PostBlock xmlns=\"\">" +
            "                               <ID>7ba91a04-9f25-463e-8227-ca3e46354c43</ID>" +
            "                               <TimeStamp>2013-04-24T11:52:30.5048515+04:00</TimeStamp>" +
            "                               <SenderIdentifier>1234ABC123</SenderIdentifier>" +
            "                           </PostBlock>" +
            "                           <SupplierBillIDs xmlns=\"\">" +
            "                               <SupplierBillID>18800000000001234567</SupplierBillID>" +
            "                           </SupplierBillIDs>" +
            "                       </DataRequest>" +
            "                   </exportData>" +
            "                </AppData>" +
            "            </MessageData>" +
            "        </UnifoTransferMsg>" +
            "    </s:Body>" +
            "</s:Envelope>";

        var signedMessage = SignCreate(oCertificate, sContent);
        // Полученный подписанный XML-документ должен проходить проверку на сайте СМЭВ
        alert(signedMessage);

        var verifyResult = Verify(signedMessage);
        if (verifyResult) {
            alert("Signature verified");
        }
    }