XML签名-PHP中的不同签名值?

XML签名-PHP中的不同签名值?,php,rsa,digital-signature,xml-signature,xml-dsig,Php,Rsa,Digital Signature,Xml Signature,Xml Dsig,我想用PHP实现一个XML数字签名。我正在测试签名的正确性 我得到了错误的签名值,所以我要一步一步地解释我在做什么,请纠正我做错了什么 我要签名的XML(无新行): 但它会产生一个不正确的签名值,如。如果我使用相同的私钥在C#中对相同的XML进行签名,我会得到正确的签名。那么,我做错了什么?我错过了什么?很明显,我签错了东西,但是我应该签什么呢?我应该在签名之前对SignedInfo元素进行散列吗 这是我的最终结果(不正确): 《代码>测试了TGGGGGGZZZZZZZZZZZZZZZZZZZZ

我想用PHP实现一个XML数字签名。我正在测试签名的正确性

我得到了错误的签名值,所以我要一步一步地解释我在做什么,请纠正我做错了什么

我要签名的XML(无新行):

但它会产生一个不正确的签名值,如。如果我使用相同的私钥在C#中对相同的XML进行签名,我会得到正确的签名。那么,我做错了什么?我错过了什么?很明显,我签错了东西,但是我应该签什么呢?我应该在签名之前对SignedInfo元素进行散列吗

这是我的最终结果(不正确):

《代码>测试了TGGGGGGZZZZZZZZZZZZZZZZZZZZZZZZZZZZZKWWZZZZZZZZZZZZGGGGGGZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZKWWWWWWZZZZ3KWWWWZZZZ3KZZZZZZ3KZZ3KZZZZ3KZZZZZZ3KZZZZ3KZZZZZZZZZZZZZZZZZZZZZZZKKKKKKKKKZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZUI+BAOD9MROZSQAIIRXG6NC/dMJyWket这是一个非常简单的数字。这是一个数字。这是一个数字。这是一个数字。这是一个数字。这是一个数字。这是一个数字。2个2个2个QY+TZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZC6QGJ0VND4EBZUQVMTNKZY3301HZ5MRQVPIPNEZ9TWMAAWDZBMRGKWBF2IVVAW3LHQ==AQAB 这是正确的结果(除签名值外,所有内容都相同):

《代码>测试》测试了GJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJGRQW10F0CF0TRGXBCPYOHMMFB2MSNYIQFZXZD0T一个新的研究成果是一个新的研究成果。这个新的研究成果是一个新的一个新的一个新的一个新的一个新的研究成果是一个新的研究成果+一个新的研究成果,一个新的研究成果是一个新的研究成果。这个研究成果是一个新的研究。这个新的研究成果是一个新的研究,这个研究成果是一个准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准准QGJ0VND4EBZUQVMTNKZY3301HZ5MRQVPIPNEZ9TWMAAWDZBMRGKWBF2IVVAW3LHQ==AQAB
要测试这两个结果或了解更多详细信息,只需复制它们并单击“验证签名”。

我解决了问题。如果有人想知道,规范化的SignedInfo是错误的,它缺少名称空间定义,名称空间定义应该来自外部签名元素

因此,规范化的SignedInfo元素现在看起来像这样(没有新行):


...

因此,在对这个SignedInfo元素签名之后,签名值是正确的。

以防万一:您也可以使用PHP DOM中的方法

您的示例可能是这样的:

$xml = new DOMDocument();
$xml->load('file.xml);
// Here, PHP takes care of canonicalization
$c14nSignedInfo = $xml->getElementsByTagName('SignedInfo')->C14N();
// From here, it's your own code:
openssl_sign($c14nSignedInfo, $signature, $privateKey, 'sha256WithRSAEncryption');
$signature = base64_encode($signature);
<SignedInfo>
    <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
    <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod>
    <Reference URI="">
        <Transforms>
            <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
        <DigestValue>EdtGJKqTvnmb0Z72M8ZxTO6Jv2jyXOohMgxVKe2Gkbo=</DigestValue>
    </Reference>
</SignedInfo>
openssl_sign($c14nSignedInfo,$signature,$privateKey,"sha256WithRSAEncryption");
$signature = base64_encode($signature);
<root><node1>test</node1><node2 attr="value" /><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><DigestValue>EdtGJKqTvnmb0Z72M8ZxTO6Jv2jyXOohMgxVKe2Gkbo=</DigestValue></Reference></SignedInfo><SignatureValue>cqkvNxWf8Z03K01SQFk/J5Z7F/l8scSFpRECCknTH840rUm2L9lKHC8UF/SGKJ4LoVxOmYKJHyq0Dx8j6shTXTK1Abm0a3Ty3IP/V0Roj+3EApq4Hwr7VOpvZjcToQj1snuUtgPZFJ6pxPWdYJ5hZhxm0C+mDMlOCgcTuWP7UIDNQ3CSC1GMcKESEkxsfEAzIXNh9wHoIY2e2HnedceFzOsJLPaLnltd1qhewJvqYCq7M1gD8e+Hv5Lyo+wG7ipvxvhAQ4Ui+BAOD9mROzSQaiirrxg6nC/dMJyWketTjKwEprZDm5BOoMoJC+kb2PvShfXrdRgA/ezWZHIaT0mLGQ==</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>nENZ+u9FZ5DSDlFRZ+0f0tZ2Kvl6QY+cjUzSc89fhixKFuexGJQcEvCrs67x8QcgwxZCuoWHk/Cdh8qd3x0EZaC+ZoZ+AF7ofoxWPHioZ86CIuxhI4Zgk0bHWibSKx8Z7EIXVrQ1nM2OvX9CdM9iVjM0yfn1ohdd1o4EKmRBbJQf6kCZMTbCdOdr8UI0xGUMjjaZN6+vGj3VYoxlQXXi11NMHDlxsCyyyjBjyCvewnTerkXAomwf92xV77siOn1VZD2/YwWarv1Hk/0WtW1c6QGj0VNd4EbzUqvMtnkzY3301hz5MRqvPiPNez9tWMaawDzbMrGGkwbF2ivVAW3LHQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></root>
<root><node1>test</node1><node2 attr="value" /><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><DigestValue>EdtGJKqTvnmb0Z72M8ZxTO6Jv2jyXOohMgxVKe2Gkbo=</DigestValue></Reference></SignedInfo><SignatureValue>OzQtkphZ+eg8JnVHzf8BVZpUZ/xMFQJhkmw5j4h2+eu8PAJh8Z9mRZH5uN/hfPFgkByBTshS/VWDNyWyF6TclQRSc8m89L8sCBQhKqGxZKjCd7V8XUIXgRgh2+Zl1JZQ/hD36XESEPazFyQ26KWq+T+m1Tc541Rv3mklfOKv2qBOqZLd/n/nRnGhFJYMp6PtPMNk/BezosGaQFUu/IhSI5tiud5ia4qETk/1G1eXAXmE4RbnVMefkysarTjizJYkGRqW10f0cF0trGxbCPyohMMfb2msnYiQfZXZd0tW41mMpH0R0AHFeC7RPxK2GzxRMRJCkNeWe65brneUtUSHzA==</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>nENZ+u9FZ5DSDlFRZ+0f0tZ2Kvl6QY+cjUzSc89fhixKFuexGJQcEvCrs67x8QcgwxZCuoWHk/Cdh8qd3x0EZaC+ZoZ+AF7ofoxWPHioZ86CIuxhI4Zgk0bHWibSKx8Z7EIXVrQ1nM2OvX9CdM9iVjM0yfn1ohdd1o4EKmRBbJQf6kCZMTbCdOdr8UI0xGUMjjaZN6+vGj3VYoxlQXXi11NMHDlxsCyyyjBjyCvewnTerkXAomwf92xV77siOn1VZD2/YwWarv1Hk/0WtW1c6QGj0VNd4EbzUqvMtnkzY3301hz5MRqvPiPNez9tWMaawDzbMrGGkwbF2ivVAW3LHQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></root>
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    ...
</SignedInfo>
$xml = new DOMDocument();
$xml->load('file.xml);
// Here, PHP takes care of canonicalization
$c14nSignedInfo = $xml->getElementsByTagName('SignedInfo')->C14N();
// From here, it's your own code:
openssl_sign($c14nSignedInfo, $signature, $privateKey, 'sha256WithRSAEncryption');
$signature = base64_encode($signature);