首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从SignatureValue计算SignedInfo

从SignatureValue计算SignedInfo
EN

Stack Overflow用户
提问于 2014-10-29 13:58:32
回答 2查看 4.5K关注 0票数 1

目前,我正试图跟踪本教程的“签名XML文档”。到目前为止,我已经能够运行c14n算法并计算适当的DigestValue

但是,我似乎无法获得SignatureValue字段的正确值。我目前正在正确计算SignedInfo标记的摘要值,因为它与作者的计算相匹配,但我似乎无法解决的问题是,签名哈希将导致与预期字符串不同的字符串。

我当前的脚本如下:

代码语言:javascript
复制
<?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,并得到了另一个不同的结果,所以我非常困惑。

代码语言:javascript
复制
$ 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是否生成了一个与预期(a25a06d339d68b625cd7383a932357889956a54e)不同的摘要。我进行了二次检查,三次检查,并确保文件内容与$c14n变量完全相同。

我到底做错了什么?

注释:--我确实检查了作者在本网站上提供的XML --看起来还不错。使用私钥与“如何操作”相同.

EN

回答 2

Stack Overflow用户

发布于 2017-11-28 23:15:22

我知道这是一个很老的帖子,但我只是被它绊倒了,因为我有一个类似的问题。

我读了同一篇教程,据我所知,您不能计算规范化字符串的sha1,而是直接将其插入openssl_sign命令中。因此,按照您的第一个示例(php),它应该说:

代码语言:javascript
复制
$c14n = '<SignedInfo... </SignedInfo>';
// Do not use sha1 here
//$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);   // your initial command
openssl_sign($c14n, $signature, $pkeyid, 'OPENSSL_ALGO_SHA1');   // modified version

// free the key from memory
openssl_free_key($pkeyid);

// Result should be: TSQUoVrQ0kg1eiltNwIhKPr ...
echo base64_encode($signature); // Should match now  ;-)
票数 3
EN

Stack Overflow用户

发布于 2014-10-30 00:02:51

我使用的方法如下:

1)获取.pem文件openssl pkcs12 -in certificate.pfx -nocerts -out privatekey.pem -nodes然后在PHP 2中)

代码语言:javascript
复制
$certificateNode = $doc3
        ->getElementsByTagName('X509Certificate')
        ->item(0);

$content = $certificateNode->C14N(FALSE, TRUE); // <-- no exclusive, with comments

$actualDigest = base64_encode(hash('SHA1', $content, true)); 
$fp = fopen('privatekey.pem', "r");
$priv_key = fread($fp, 8192);
fclose($fp);
$passphrase = 'the pasphrase';
$res = openssl_get_privatekey($priv_key,$passphrase);
openssl_private_encrypt($actualDigest, $crypttext, $res);
$signatureValueBase64 = base64_encode($crypttext);

我希望这能帮到你。jrcscarrillo@gmail.com

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26632282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档