Генерация подписи XML

Я застрял, пытаясь создать правильный способ подписать мой XML в течение двух дней.

Вот как должна выглядеть часть подписи:

<Signature>
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>cTKLzl3+JJitmqnEmdv4x/h3HZU=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>GBDvnBoVHlJJ+96+aVqS34Ei7jHRDXm7n21SeFxD42Cqah1FXK0lCz6z/lp3ptDPYMLljCcoYYSX miRdD3/in4inMmn6nb/ZGVPHo26K+gphPg3ChhZGz5YA1cLTaBNMhC0yqSNuuqNnyxPuLix2U7a3 g5jTCmm4F8ehqhP2JZ8pSVTziyT0UgwjB9OUrHEa8qMxRgIG4t4nxTz0+1norLZf3frhHwnu0XE4 UaHCfP1eWV81Npqgdj3TrGUeOjfkEqgxKUEP/E3TLjDNxUm7gjMSszaG1I58qKPEAqfoDWuOhyZi TsuGyu682q9qouo12A6RzH4MatA8i/nUagQ02Q==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>i+rh6NJ7Z6Q8XiMSVK/Z8DYXIyk5j7N9GUX8AOSKONabse4us7/ogR0x7OOf0FsrdxAhQls59Wn1vDxujSVOu3v1JhML/v/WK8glcxM433oEEpb0C56XRHlt27Qkbsn6v3njC1z0NGyDFdAtg5PaMx7YmjyWR6ezMKj9wR5cK4CRZ7idm2PwzQaLUDFm7wUFXudZNkQ6pb60OvDw4ey1t68EVCPtq4nGdHG+3jlSDTTJc/03qk50pa6Nb/t5+EWsE3jFt/uhHim1rC2pMf5UrT26FL6/DjA0PxQFecc76zeuv3xbGSP7B7ubpG8fyatGb4oLB4eU0ceCJvqljGMP0w==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>

Я получаю DigestValue правильно, делая это

$ns = $xml->documentElement->namespaceURI;
$body = $xml
->getElementsByTagNameNS($ns, 'paymentRequest')
->item(0);

$xml = $body->C14N(false, true);
$digest = base64_encode(hash('SHA1', $xml, true));

Я тоже получил часть модуля, взяв ее из сертификата .pem документа.
Единственная часть, которую я не могу создать, это SignatureValue.

Я пытаюсь сделать это так:

$signature = "";

$fp = fopen(__API__ . 'elvartai/keys/payment/testKey.pem', "r");
$priv_key = fread($fp, filesize(__API__ . 'elvartai/keys/payment/testKey.pem'));
fclose($fp);

$pkeyid = openssl_get_privatekey($priv_key);
openssl_sign($digest, $signature, $pkeyid, "sha1");

$base64_signature = base64_encode($signature);

$ digest — это значение digest, сгенерированное мной ранее cTKLzl3+JJitmqnEmdv4x/h3HZU= и это делает пример. Что я делаю неправильно?

Это значение SignatureValue, которое я получаю

H8/jxi2Z0fA1qTtBG8bwKc2XSN0fJpHTPyypyYBMV/6uQCS4F0UdEefftFeuCEdOyablK67RhN+6wtLMuQDgVLfYjPD+rB9A/FRgQljDVHaMhjIxODpG2z8w3A/MJc86D2Fj0ylRKXykSNbA2n8b7MP4ESemoBJ7sm3xGAMb7z8QPJFfIVj4XXFbnXHMnw9nuwt4HD9e0VuZtOQWKPgVpdsLqQtsD5zQksWTb1HzhGO+jfm6l9dsC1k9BbpyO5GgOL25UVyaRHeOIF+Lxp9TAXmUXs7Y1teYXMfaHzIlRTXVjIdWPiJGM6U8gzSu6fpFQK8yEOngNH4137kEZ6f1RQ==

1

Решение

Расчет дайджеста не является вашей ответственностью с целью подписания. Первый параметр для openssl_sign() Функция должна быть данными, которые вы хотите подписать ($xml в вашем примере), а не дайджест, который вы рассчитали сами (результат hash() позвоните в вашем примере) или base64_encode()d значение этого дайджеста (как вы сделали с $digest).

В рамках генерации подписи openssl_sign()Дайджест будет рассчитан. Вот почему вы проходите в "sha1" значение, чтобы сказать ему, какой алгоритм дайджеста использовать для этого.

Небольшое замечание относительно последнего: глядя на openssl_sign документация, это обеспечивает лучший способ указать алгоритм дайджеста, используя OPENSSL_ALGO_SHA1 в отличие от вашей буквальной строки.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector