8

手動の参照検証 (すべての参照要素を正規化 --> SHA1 --> Base64 --> DigestValue コンテンツと同じかどうかを確認) は正常に実行できますが、SignatureValue の検証に失敗します。正規化してハッシュする SignedInfo は次のとおりです。

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
 <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
 <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
 <ds:Reference URI="#element-1-1291739860070-11803898">
  <ds:Transforms>
   <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
  </ds:Transforms>
  <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
  <ds:DigestValue>d2cIarD4atw3HFADamfO9YTKkKs=</ds:DigestValue>
 </ds:Reference>
 <ds:Reference URI="#timestamp">
  <ds:Transforms>
   <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
  </ds:Transforms>
  <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
  <ds:DigestValue>YR/fZlwJdw+KbyP24UYiyDv8/Dc=</ds:DigestValue>
 </ds:Reference>
</ds:SignedInfo>

タグ間のすべてのスペースを削除した後 (要素全体を 1 行にまとめた後)、次の sha1 ダイジェストを取得します (Base64):

6l26iBH7il/yrCQW6eEfv/VqAVo=

ここで、SignatureValue コンテンツの復号化後に同じダイジェストを見つけることを期待していますが、別のより長い値が得られます。

MCEwCQYFKw4DAhoFAAQU3M24VwKG02yUu6jlEH+u6R4N8Ig=

解読のためのJavaコードは次のとおりです。

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    
  DocumentBuilder builder = dbf.newDocumentBuilder();  
  Document doc = builder.parse(new File(inputFilePath));
  NodeList nl = doc.getElementsByTagName("ds:SignatureValue");
  if (nl.getLength() == 0) {
     throw new Exception("Cannot find SignatureValue element");
   }
  String signature = "OZg96GMrGh0cEwbpHwv3KDhFtFcnzPxbwp9Xv0pgw8Mr9+NIjRlg/G1OyIZ3SdcOYqqzF4/TVLDi5VclwnjBAFl3SEdkyUbbjXVAGkSsxPQcC4un9UYcecESETlAgV8UrHV3zTrjAWQvDg/YBKveoH90FIhfAthslqeFu3h9U20=";
  X509Certificate cert = X509Certificate.getInstance(new FileInputStream(<a file path>));
  PublicKey pubkey = cert.getPublicKey();
  Cipher cipher = Cipher.getInstance("RSA","SunJCE");
  cipher.init(Cipher.DECRYPT_MODE, pubkey);
  byte[] decodedSignature = Base64Coder.decode(signature);
  cipher.update(decodedSignature);
  byte[] sha1 = cipher.doFinal();


  System.out.println(Base64Coder.encode(sha1));

私を大いに混乱させるのは、2 つのダイジェストのサイズが異なることですが、もちろん、2 つの計算からまったく同じ値を取得する必要もあります。助言がありますか?ありがとうございました。

4

2 に答える 2

8

MCEwCQYFKw4DAhoFAAQU3M24VwKG02yUu6jlEH+u6R4N8Ig=は、DER でエンコードされた ASN.1 構造の Base64 エンコードです。SEQUENCE最初に an を含むa AlgorithmIdentifier(これは SHA-1 であり、SHA-1 は何も受け入れないため、パラメーターはありません)OCTET STRINGを含み、次に実際の 20 バイト値を含む an を含みます。16 進数の値は次のとおりdccdb8570286d36c94bba8e5107faee91e0df088です。

この ASN.1 構造は、標準のRSA 署名メカニズムの一部です。非標準の構造にアクセスするためにRSA復号化を使用しています。RSA 暗号化RSA 署名は 2 つの異なるアルゴリズムであるため、実際には何でも取得できて幸運です。両方とも同じ種類のキー ペアをフィードし、「古いスタイル」(別名「PKCS#1 v1.5」) の署名と暗号化スキームが同様のパディング手法を使用している (類似しているが同一ではない; それはRSA の Java 実装が、復号化モードで使用されたときに署名のパディングを詰まらせなかったことは、すでに少し驚くべきことです)。

とにかく、6l26iBH7il/yrCQW6eEfv/VqAVo=20 バイト値の Base64 エンコードは、16 進数で次のとおりea5dba8811fb8a5ff2ac2416e9e11fbff56a015aです。これは、タグ間のすべての空白を削除した後、上に示した XML 構造をハッシュすることによって得られるものです。すべての空白を削除することは、適切な正規化ではありません。実際、私の知る限り、空白はタグ内の属性間でのみ影響を受けますが、外部の空白は変更しないでください (行末の正規化 [LF / CR+LF のこと] を除く)。

署名の生成に使用された値 ( dccdb85...) は、表示されている XML オブジェクトを使用し、先頭のスペースを削除することで取得できます。明確にするために、XML をファイルにコピーして貼り付け、各行の先頭のスペース (0 ~ 3 個のスペース) を削除します。すべての行末が単一の LF (0x0A バイト) を使用していることを確認し、最後の LF (の直後のもの) を削除します</ds:SignedInfo>。結果のファイルの長さは 930 バイトである必要があり、その SHA-1 ハッシュは期待されるdccdb85...値です。

于 2010-12-13T16:25:30.247 に答える
0

特定の XML トークンを見て、いくつかのことが言えます。

  • Canonicalization メソッドExclusive XML Canonicalization Version 1.0を使用しています。これは、正しいダイジェスト値と署名を確実に生成する上で非常に重要な要素です。

  • 参照ダイジェストの計算と、署名を生成する前のSignedInfoの正規化の両方に、同じ Canonicalization メソッドを使用しています。

Exclusive XML Canonicalizaiton Version 1.0 の仕様は W3C によって作成され、それぞれのW3C 勧告に記載されています。値を手動で計算している場合は、仕様に正確に準拠していることを確認してください。正規化を正しく行うのは難しいことであり、これを正しく行うことが非常に重要です。そうしないと、値が正しくなくなります。

XML 署名の検証プロセスについて説明した広範な記事を書きました。記事は私のブログにあります。XML署名には多くの複雑さがあるため、私の回答よりもはるかに詳細にプロセスを説明しています。また、一般的な仕様と RFC へのリンクも含まれています。

于 2012-07-07T02:45:08.717 に答える