2011-01-26 27 views
14

私は最初からX.509証明書ジェネレータを実装しようとしています(私は既存のものについて知っていますが、もう1つは必要です)。私が理解できないのは、証明書のSHA-1(またはその他の)指紋を計算する方法です。X.509証明書のSHA-1指紋の計算方法は?

RFC5280は、署名機能への入力が、DERでエンコードされたtbsCertificateフィールドであることを示します。残念ながら、私が計算するハッシュは、OpenSSLによって生成されたハッシュとは異なります。ここにステップバイステップの例があります。

  1. のOpenSSLのX509ツールを使用して証明書を生成する(バイナリDER形式で、ない ASCII PEM)
  2. DDを用いてTBSフィールドを抽出openssl x509 -fingerprint
  3. を使用して、SHA-1ハッシュを計算する(または何かそれ以外のファイルに保存してください。 sha1sumユーティリティを使用してそのハッシュを計算してください

ここで、ステップ2と3で得られるハッシュは異なります。誰かが私に間違っているかもしれないことをヒントを与えることができますか?

+0

あなたがたtbsCertificateのSHA-1ハッシュを計算するときに、あなたは[PKCS#1]を使用している(http://tools.ietf.org/html/ [rfc 3279](http://tools.ietf.org/html/rfc3279)で指定されているように、 – sarnold

+0

Uhm ... RFC2313(PKCS#1)は、RSA暗号化のみを指定します。私が理解する限り、パディングはSHA-1の計算段階では必要ありませんか? –

+0

ああ、ところで、ステップ3ではsha1sumユーティリティを使ってハッシュを計算します –

答えて

16

OK、これは、OpenSSLにより算出した指紋は、単に全体(そのDERバイナリエンコーディングでは、ない ASCII PEMの1!)証明書、TBSの部分だけではなく、オーバーハッシュであることが判明したので、私は思った。証明書のダイジェストを計算する気に誰のための

が、それは別の方法で行われます。ハッシュは、DERでエンコードされた(再び、ない PEM文字列)TBSの一部のみ、そのASNを含む上で計算されます。 1ヘッダー(ID 0x30 == ASN1_SEQUENCE | ASN1_CONSTRUCTEDと長さフィールド)。証明書のASN.1ヘッダーは考慮されていないことに注意してください。

+1

あなたはあなたの答え(または質問)に、将来の参照のために正確にddでTBS部分を抽出した方法を追加することができます:) –

+0

ああ...かなり前に、覚えていない詳細。私は手動でTBSのオフセットと長さを証明書の16進数ダンプから抽出し、これらの値をddの引数として使用しました。何も複雑ではありません –

+0

@Roman Dあなたの答えは、最初の段落の '第2段落には「部分のみ」が含まれています。これは間違いですか?証明書のTBS部分は何ですか?私は私のGoogle検索から有用な何かを見つけることができませんでした。 – chitti

1

フィンガープリントは、.netの用語 "Thumbprint"に似ています。コードスニペットの下に指紋を計算するためのお手伝いをする必要があります

public String generateFingerPrint(X509Certificate cert) throws CertificateEncodingException,NoSuchAlgorithmException { 

MessageDigest digest = MessageDigest.getInstance("SHA-1"); 
byte[] hash = digest.digest(cert.getEncoded[]); 

final char delimiter = ':'; 
// Calculate the number of characters in our fingerprint 
     // ('# of bytes' * 2) chars + ('# of bytes' - 1) chars for delimiters 
     final int len = hash.length * 2 + hash.length - 1; 
     // Typically SHA-1 algorithm produces 20 bytes, i.e. len should be 59 
     StringBuilder fingerprint = new StringBuilder(len); 

     for (int i = 0; i < hash.length; i++) { 
     // Step 1: unsigned byte 
     hash[i] &= 0xff; 

     // Steps 2 & 3: byte to hex in two chars 
     // Lower cased 'x' at '%02x' enforces lower cased char for hex value! 
     fingerprint.append(String.format("%02x", hash[i])); 

     // Step 4: put delimiter 
     if (i < hash.length - 1) { 
      fingerprint.append(delimiter); 
     } 
     } 

     return fingerprint.toString(); 


    } 
関連する問題