dougao7801 2018-06-21 14:48
浏览 210

生成XML签名

I've been stuck trying to generate a valid way to sign my xml for two days now.

This is how a signature part should look like:

<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>

I get the DigestValue correctly by doing this

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

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

I get the Modulus part ok too by taking it from the certificate .pem document. The only part I can't seem to generate is the SignatureValue.

I try to do it like so:

$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 is the digestValue I generated before cTKLzl3+JJitmqnEmdv4x/h3HZU= and it does mach the example. What am I doing wrong?

This is the SignatureValue that I get

H8/jxi2Z0fA1qTtBG8bwKc2XSN0fJpHTPyypyYBMV/6uQCS4F0UdEefftFeuCEdOyablK67RhN+6wtLMuQDgVLfYjPD+rB9A/FRgQljDVHaMhjIxODpG2z8w3A/MJc86D2Fj0ylRKXykSNbA2n8b7MP4ESemoBJ7sm3xGAMb7z8QPJFfIVj4XXFbnXHMnw9nuwt4HD9e0VuZtOQWKPgVpdsLqQtsD5zQksWTb1HzhGO+jfm6l9dsC1k9BbpyO5GgOL25UVyaRHeOIF+Lxp9TAXmUXs7Y1teYXMfaHzIlRTXVjIdWPiJGM6U8gzSu6fpFQK8yEOngNH4137kEZ6f1RQ==
  • 写回答

1条回答 默认 最新

  • dtol41388 2018-06-23 14:39
    关注

    Calculation of the digest is not your responsibility for the purpose of signing. The first parameter to the openssl_sign() function should be the data that you want to sign ($xml in your example), not a digest that you calculated yourself (the result of the hash() call in your example) or the base64_encode()d value of that digest (like you did with $digest).

    As part of the signature generation by openssl_sign(), the digest will be calculated. That is why you pass in the "sha1" value, to tell it which digest algorithm to use for that.

    A minor remark concerning the latter: looking at the openssl_sign documentation, it provides a better way to specify the digest algorithm, using OPENSSL_ALGO_SHA1 as opposed to your literal string.

    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么