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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Lirein  
#1 Оставлено : 29 марта 2020 г. 13:21:52(UTC)
Lirein

Статус: Активный участник

Группы: Участники
Зарегистрирован: 18.09.2015(UTC)
Сообщений: 86
Мужчина
Российская Федерация
Откуда: На работе

Сказал «Спасибо»: 18 раз
Поблагодарили: 52 раз в 40 постах
Добрый день, пытаюсь подписать платежное поручение на PHP, для интеграфции с Альфа-линк, перепробовал кучу способов, и похоже единственный который будет рабочим - использовать PHPCades.

Попытка подписать XML согласно примеру подписания XML для СМЭВ https://cpdn.cryptopro.r...s-sign-xml-template.html
и примеру подписанной платежки https://github.com/alfa-...gned_payment_example.txt
Завершается ошибкой: The system was unable to parse the requested XML data. (0x800705B9) или
Код:

#!/usr/bin/php
<?php

function SetupStore($location, $name, $mode)
{
    $store = new CPStore();
    $store->Open($location, $name, $mode);
    return $store;
}

function SetupCertificates($location, $name, $mode)
{
    $store = SetupStore($location, $name, $mode);
    return $store->get_Certificates();
}

function SetupCertificate($location, $name, $mode,
                           $find_type, $query, $valid_only,
                           $number)
{
    $certs = SetupCertificates($location, $name, $mode);
    if ($find_type != NULL)
    {
        $certs = $certs->Find($find_type, $query, $valid_only);
        if (is_string($certs))
            return $certs;
        else
            return $certs->Item($number);
    }
    else
    {
        $cert = $certs->Item($number);
        return $cert;
    }
}

try
{
    $content = '<?xml version="1.0" encoding="utf-8"?>w.w3.org/2000/09/xmldsig#enveloped-signature"/>
    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.06" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><CstmrCdtTrfInitn><GrpHdr><MsgId>1585472712</MsgId><CreDtTm>2020-03-29T14:05:13</CreDtTm><NbOfTxs>1</NbOfTxs><CtrlSum>100.12</CtrlSum></GrpHdr><PmtInf><PmtInfId>1585472713</PmtInfId><PmtMtd>TRF</PmtMtd><NbOfTxs>1</NbOfTxs><ReqdExctnDt>2020-03-29</ReqdExctnDt><Dbtr><Nm>ООО "Рога и Копыта"</Nm><Id><OrgId><Othr><Id>7701234567</Id></Othr></OrgId></Id></Dbtr><DbtrAcct><Id><Othr><Id>40702810901300013000</Id></Othr></Id></DbtrAcct><DbtrAgt><FinInstnId><ClrSysMmbId><MmbId>044525593</MmbId></ClrSysMmbId><Nm>АО "АЛЬФА-БАНК", Г МОСКВА, УЛ КАЛАНЧЁВСКАЯ, 27</Nm></FinInstnId></DbtrAgt><DbtrAgtAcct><Id><Othr><Id>30101810200000000593</Id></Othr></Id></DbtrAgtAcct><CdtTrfTxInf><RmtInf><Strd><RfrdDocInf><RltdDt>2020-03-29T14:05:13</RltdDt></RfrdDocInf></Strd><Ustrd>Оплата по договору №200120, Включая НДС 20.02</Ustrd></RmtInf><PmtId><InstrId>1585472714</InstrId><EndToEndId>472714</EndToEndId></PmtId><Amt><InstdAmt>100.12</InstdAmt></Amt><PmtTpInf><SvcLvl><Cd>NURG</Cd></SvcLvl></PmtTpInf><Purp><Prtry>NORM</Prtry></Purp><Tax><Rcrd><AddtlInf>VTIN</AddtlInf><TaxAmt><Rate>20</Rate></TaxAmt></Rcrd><Dbtr><TaxTp>77001000</TaxTp></Dbtr><Cdtr><TaxTp>72001000</TaxTp></Cdtr></Tax><Cdtr><Nm>ООО "Ромашка"</Nm><Id><OrgId><Othr><Id>7209876543</Id></Othr></OrgId></Id></Cdtr><CdtrAcct><Id><Othr><Id>40701810400000000225</Id></Othr></Id></CdtrAcct><CdtrAgt><FinInstnId><ClrSysMmbId><MmbId>047102651</MmbId></ClrSysMmbId><Nm>Тюменское отделение № 29 Сбербанка: ПАО Сбербанк России</Nm></FinInstnId></CdtrAgt><CdtrAgtAcct><Id><Othr><Id>30101810800000000651</Id></Othr></Id></CdtrAgtAcct></CdtTrfTxInf></PmtInf><SplmtryData><Envlp><SngtrSt><ds:Signature>
    <ds:SignedInfo>cate>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
    <ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/>
    <ds:Reference URI="">
    <ds:Transforms>
     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
     <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
     <ds:Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2">
      <dsig-xpath:XPath xmlns:dsig-xpath="http://www.w3.org/2002/06/xmldsig-filter2" Filter="subtract">//ds:Signature</dsig-xpath:XPath>
     </ds:Transform>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/>
    <ds:DigestValue></ds:DigestValue>
    </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue></ds:SignatureValue>
    <ds:KeyInfo>
    <ds:X509Data>
    <ds:X509Certificate>
    </ds:X509Certificate>
    </ds:X509Data>
    </ds:KeyInfo>
    </ds:Signature>
    </SngtrSt></Envlp></SplmtryData></CstmrCdtTrfInitn></Document>
';
    $cert = SetupCertificate(CURRENT_USER_STORE, "my", STORE_OPEN_READ_ONLY,
    CERTIFICATE_FIND_SHA1_HASH, "5dd37e3b8b4130909c8716acef19fb605434b9d2", 0,
                             1);

    if (!$cert)
    {
        printf("Certificate not found\n");
        return;
    }
    $certData = $cert->export(0);

    printf("Certificate:\n%s\n", $certData);

    $signer = new CPSigner();
    $signer->set_Certificate($cert);
    $signer->set_KeyPin('666213');
    $signer->set_Options(2);

    $sd = new CPSignedXml();
    $sd->set_SignatureType(2);
    $sd->set_Content($content);
    $sd->set_DigestMethod('urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256');
    $sd->set_SignatureMethod('urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256');
    $signedXml = $sd->Sign($signer, "/*[local-name()='Document' and namespace-uri()='urn:iso:std:iso:20022:tech:xsd:pain.001.001.06']".
            "/*[local-name()='CstmrCdtTrfInitn' and namespace-uri()='urn:iso:std:iso:20022:tech:xsd:pain.001.001.06']".
            "/*[local-name()='SplmtryData' and namespace-uri()='urn:iso:std:iso:20022:tech:xsd:pain.001.001.06']".
            "/*[local-name()='Envlp' and namespace-uri()='urn:iso:std:iso:20022:tech:xsd:pain.001.001.06']".
            "/*[local-name()='SngtrSt' and namespace-uri()='urn:iso:std:iso:20022:tech:xsd:pain.001.001.06']");
    printf("%s\n", $signedXml);
//    $sd->VerifyHash($hash, $sm, $cert1);
//    printf("Verify OK\n");
}
catch (Exception $e)
{
    printf($e->getMessage());
}

?>


Пример подписания на яве есть у альфы тут: https://github.com/alfa-...entSignatureExample.java

Пробовал делать реализацию вручную с помощю RawSignature и парсингом ASN1 структуры Cades-BES подписи. Воз и ныне там.

Подскажите пожалуйста, в чем ошибка?
--- Эльфиек на всех не хватает...
*** А всё таки, она вертится!
thanks 1 пользователь поблагодарил Lirein за этот пост.
retest оставлено 07.06.2022(UTC)
Offline Александр Лавник  
#2 Оставлено : 29 марта 2020 г. 14:55:06(UTC)
Александр Лавник

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

Группы: Участники
Зарегистрирован: 30.06.2016(UTC)
Сообщений: 3,486
Мужчина
Российская Федерация

Сказал «Спасибо»: 53 раз
Поблагодарили: 802 раз в 741 постах
Здравствуйте.

Странный тег в XML:

Код:
<ds:SignedInfo>cate>
Техническую поддержку оказываем тут
Наша база знаний
Offline Lirein  
#3 Оставлено : 29 марта 2020 г. 15:07:01(UTC)
Lirein

Статус: Активный участник

Группы: Участники
Зарегистрирован: 18.09.2015(UTC)
Сообщений: 86
Мужчина
Российская Федерация
Откуда: На работе

Сказал «Спасибо»: 18 раз
Поблагодарили: 52 раз в 40 постах
Автор: Александр Лавник Перейти к цитате
Здравствуйте.

Странный тег в XML:

Код:
<ds:SignedInfo>cate>


Спасибо, ошибка вылезла при копировании XML. Исправил, получаю: The parameter is incorrect. (0x80070057)



UPD: При задании XPath как //ds:Signature - получаю: The system was unable to parse the requested XML data. (0x800705B9)

Отредактировано пользователем 29 марта 2020 г. 15:11:08(UTC)  | Причина: Не указана

--- Эльфиек на всех не хватает...
*** А всё таки, она вертится!
Offline two_oceans  
#4 Оставлено : 30 марта 2020 г. 6:51:23(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 1,602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 396 раз в 366 постах
Похоже на вот эту тему https://www.cryptopro.ru...aspx?g=posts&t=11568
Как я понимаю, если шаблон подписи с незаполнеными данными в документе только один - можно не указывать XPath.

Вообще расположение шаблона несколько интересное. Еще бы немного и было просто enveloped, а так дополнительные трансформы вычитания и шаблон добавлять пришлось.
Offline Lirein  
#5 Оставлено : 30 марта 2020 г. 7:15:44(UTC)
Lirein

Статус: Активный участник

Группы: Участники
Зарегистрирован: 18.09.2015(UTC)
Сообщений: 86
Мужчина
Российская Федерация
Откуда: На работе

Сказал «Спасибо»: 18 раз
Поблагодарили: 52 раз в 40 постах
Автор: two_oceans Перейти к цитате

Вообще расположение шаблона несколько интересное. Еще бы немного и было просто enveloped, а так дополнительные трансформы вычитания и шаблон добавлять пришлось.


Да все вроде верно. Что интересно - что через CPRawSignature(). что через Cades-BES/ASN1 получаю одинаоквую длину подписи и Digest, формирую XMLDsig вручную, все вроде бу корректно, но подпись в банке проверку не проходит, уже написал в техподдержку, жду ответа, но скорее всего на "праздниках" будет тишина.

Пробовал проверить подпись из примера, ещё чудесатее, проверку не проходит, ни через CPSignedXML, на через CPRawSignature.

Дата изменения: пользователем 30 марта 2020 г. 7:17:35(UTC)  | Причина: Не указана

--- Эльфиек на всех не хватает...
*** А всё таки, она вертится!
Offline Lirein  
#6 Оставлено : 30 марта 2020 г. 9:42:28(UTC)
Lirein

Статус: Активный участник

Группы: Участники
Зарегистрирован: 18.09.2015(UTC)
Сообщений: 86
Мужчина
Российская Федерация
Откуда: На работе

Сказал «Спасибо»: 18 раз
Поблагодарили: 52 раз в 40 постах
Переделал на проверку теста подписи вручную, даже Digest высчитывается по разному для разных случаев.



Не пойму тогда как работает каноникализация, учитывая что с PreserveSpaces оставляет оригинальное форматирование из примера, а c ним теги идут подряд. Метод каноникализации вроде в PHP тот же что и указан в XML, то есть все пробелы и отступы сохраняются "Как есть".

Отредактировано пользователем 30 марта 2020 г. 9:47:29(UTC)  | Причина: Не указана

--- Эльфиек на всех не хватает...
*** А всё таки, она вертится!
thanks 1 пользователь поблагодарил Lirein за этот пост.
Александр Лавник оставлено 30.03.2020(UTC)
Offline Lirein  
#7 Оставлено : 30 марта 2020 г. 20:50:42(UTC)
Lirein

Статус: Активный участник

Группы: Участники
Зарегистрирован: 18.09.2015(UTC)
Сообщений: 86
Мужчина
Российская Федерация
Откуда: На работе

Сказал «Спасибо»: 18 раз
Поблагодарили: 52 раз в 40 постах
Получилось. Руками так и не поборол - выяснил что в PHP 7.2 изменилась трансформа каноникализации на стандарт 2017 года.
В итоге разобрался с подписью SignedXML - передаю XPath для поиска последней подписи в документе.

$signedXml = $sd->Sign($signer, "//*[local-name()='Signature' and position()=last()]");

Может кому пригодится:

Отредактировано пользователем 30 марта 2020 г. 21:19:34(UTC)  | Причина: Не указана

--- Эльфиек на всех не хватает...
*** А всё таки, она вертится!
thanks 2 пользователей поблагодарили Lirein за этот пост.
two_oceans оставлено 31.03.2020(UTC), retest оставлено 07.06.2022(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.