В настоящее время я пытаюсь найти this tutorial в разделе «Подписание XML-документа». До сих пор мне удалось запустить алгоритм c14n и вычислить соответствующий DigestValue
.Вычисление SignatureValue от SignedInfo
Однако я не могу получить правильное значение для поля SignatureValue
. В настоящее время я вычисляю значение дайджеста для тега SignedInfo
, так как он соответствует расчету автора, но проблема, которую я не могу решить, заключается в том, что подписание хэша приводит к другой строке, ожидаемой.
Моего текущий сценарий выглядит следующим образом:
<?php
$c14n = '<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>UWuYTYug10J1k5hKfonxthgrAR8=</DigestValue>
</Reference>
</SignedInfo>';
echo sha1($c14n).PHP_EOL.PHP_EOL; // a25a06d339d68b625cd7383a932357889956a54e OK !!
$data = sha1($c14n); // sha1($c14n,true) wont work either
$pkeyid = openssl_pkey_get_private("file://key.txt",'password'); // PK
// compute signature
openssl_sign($data, $signature, $pkeyid);
// free the key from memory
openssl_free_key($pkeyid);
// Result should be: TSQUoVrQ0kg1eiltNwIhKPr ...
echo base64_encode($signature); // Wont match!
?>
Я не уверен, должна ли быть подписана сырая версия или шестигранные один. В любом случае полученные значения не совпадают, поэтому должно быть что-то еще. Я использовал openssl
и придумал другой результат, поэтому я очень смущен.
$ cat signedinfo.txt
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>UWuYTYug10J1k5hKfonxthgrAR8=</DigestValue>
</Reference>
</SignedInfo>
$ openssl dgst -sha1 -sign key.txt -out sign-ID.bin signedinfo.txt
$ php -r 'echo base64_encode(file_get_contents("sign-ID.bin"));'
bFGI6KjCXtu1mAPFzvfyPkhZU5/CsYIR2IIQ0/n+6zZYqVAuIqjtgrc+xQXOQhf5RTcVR2zr/teWSSjmQvaHzFn4NhXGxvEMng1Kqg04XpQS41OLgAjaNMRW5iU4cRwFW1VMPAiHkjZggDkDgG8pSn6zdQh0yUEgo+86zJI6kbQ=
Я был в состоянии проверить, что OpenSSL генерирует Diferent переварить, чем ожидалось (a25a06d339d68b625cd7383a932357889956a54e), если запущен из терминала. Я проверил дважды, проверил три раза и убедился, что содержимое файла точно так же, как и переменная $c14n
.
Что именно я делаю неправильно?
Примечания: Я сделал проверить XML, что автор представил на this website и это, кажется, в порядке. private key used - это то же самое, что и на How-To.
Хуан, спасибо за ответ. Кажется, он все еще работает. Возвращаемое значение - D8U622bvnhiEXBTfcD90 ... что неверно. Я правильно вычисляю значение дайджеста для тега SignedInfo, но не могу заставить его работать. –
Преобразование строки в Base64 должно быть последним. $ actualDigest не должен быть закодирован Base64! – canolucas