2017-02-02 85 views
2

私はPHPでXMLデジタル署名を実装したいと考えています。私はthis verifierに署名の正しさをテストしています。XML署名 - PHPの署名値が異なる?

私は間違った署名値を得ているので、私は何をしているのかを段階的に説明し、私が間違っていることを修正してください。

私は(改行なし)署名するXML

<root> 
    <node1>test</node1> 
    <node2 attr="value" /> 
</root> 

まずは、私は、XMLを正規化し、それが正しいダイジェスト値を生成するSHA256を使用してハッシュ。

、たSignedInfo XML要素の作成とそれが(改行せず)canonicalizing:

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

最後、RSA-SHA256を使用してSignedInfoエレメントの署名。これは誤った結果をもたらす部分です。

署名は、次のコード行を使用して計算される:

openssl_sign($c14nSignedInfo,$signature,$privateKey,"sha256WithRSAEncryption"); 
$signature = base64_encode($signature); 

しかしverifierにより述べたように、それは、間違った署名値をもたらします。同じ秘密鍵を使ってC#で同じXMLに署名すると、正しい署名が得られます。だから、私は何が間違っているの?私は何が欠けていますか?明らかに、私は間違ったものに署名していますが、私はそれに署名する必要がありますか?署名する前にSignedInfo要素をハッシュする必要がありますか? (すべてが署名値を除いて、同じである)

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

両方の結果をテストする方法や詳細については、hereをコピーして「署名の検証」をクリックしてください。

答えて

1

私はこの問題を解決しました。もし誰かが知りたいのであれば、正規化されたSignedInfoが間違っていて、名前空間の定義が欠落していました。これは外側のSignature要素から来るはずです。

ので、正規化さSignedInfoエレメントは今この(改行なし)次のようになります。

<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
    ... 
</SignedInfo> 

したがって、このSignedInfoエレメントに署名した後、署名値が正しいです。

1

PHPのDOMの一部であるC14Nメソッドを使用することもできます。

はあなたの例のためにこのようなものが考えられます。

$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); 
関連する問題