6

証明書を2つ持っています。1 つの証明書が別の証明書の発行者です。

私の発行者証明書が実際に発行者であることをJavaコードで確認するにはどうすればよいですか?

私は、自分の証明書の AuthorityKeyIdentifier と発行者証明書の SubjectKeyIdentify が同じでなければならないことを知っています。確認しましたが、同じです。

しかし、Javaコードを使用すると、次の結果が得られます。

    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");

    InputStream usrCertificateIn = new FileInputStream("/usr.cer");
    X509Certificate cert = (X509Certificate) certFactory.generateCertificate(usrCertificateIn);

    InputStream SiningCACertificateIn = new FileInputStream("/siningCA.cer");
    X509Certificate issuer = (X509Certificate) certFactory.generateCertificate(SiningCACertificateIn);

    byte[] octets = (ASN1OctetString.getInstance(cert.getExtensionValue("2.5.29.35")).getOctets());     
    System.out.println(Arrays.toString(octets) + " bouncycastle, AuthorityKeyIdentifier");
    System.out.println(Arrays.toString(cert.getExtensionValue("2.5.29.35")) + "java.security, AuthorityKeyIdentifier");

    octets = ASN1OctetString.getInstance(issuer.getExtensionValue("2.5.29.14")).getOctets();
    System.out.println((Arrays.toString(octets) + "bouncycastle, SubjectKeyIdentifie "));
    System.out.println(Arrays.toString(issuer.getExtensionValue("2.5.29.14")) + "java.security, SubjectKeyIdentifie ");

その結果は次のとおりです。

[48, 22, -128, 20, 52, -105, 49, -70, -24, 78, 127, -113, -25, 55, 39, 99, 46, 6, 31, 66, -55, -86、 -79、113 ] bouncycastle、AuthorityKeyIdentifier

[ 4 , 24, 48, 22, -128, 20, 52, -105, 49, -70, -24, 78, 127, -113, -25, 55, 39, 99, 46, 6, 31, 66 , -55, -86, -79, 113 ]java.security, AuthorityKeyIdentifier

そして、同じでなければならない別のバイト配列が、配列の先頭に別のバイトが追加されます。

[ 4, 20, 52, -105, 49, -70, -24, 78, 127, -113, -25, 55, 39, 99, 46, 6, 31, 66, -55, -86, -79 、113 ] bouncycastle、SubjectKeyIdentify

[4, 22, 4, 20, 52, -105, 49, -70, -24, 78, 127, -113, -25, 55, 39, 99, 46, 6, 31, 66, -55, - 86、-79、113 ]java.security、SubjectKeyIdentify

質問 1) キー識別子を計算して同じ配列を取得できますか?

質問 2) ある証明書が別の証明書の発行者であることを証明する別の方法はありますか。

4

2 に答える 2

8

AuthorityKeyIdentifierSubjectKeyIdentifier定義が異なります。

AuthorityKeyIdentifier ::= SEQUENCE {
  keyIdentifier             [0] KeyIdentifier           OPTIONAL,
  authorityCertIssuer       [1] GeneralNames            OPTIONAL,
  authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }

SubjectKeyIdentifier ::= KeyIdentifier

KeyIdentifier ::= OCTET STRING

( RFC 5280のセクション 4.2.1.1 および 4.2.1.2 )

したがって、拡張機能の値を比較するだけでは機能しません。代わりに、KeyIdentifierBouncyCastle ASN.1 ヘルパー クラスなどを使用して、内容を抽出して比較する必要があります。

ところで、実際のキー識別子のバイトは

52, -105, 49, -70, -24, 78, 127, -113, -25, 55, 39, 99, 46, 6, 31, 66, -55, -86, -79, 113

その前の 4, 20 は、20 バイトの長さの OCTET STRING を示します。AuthorityKeyIdentifier では、暗黙的なタグ付けにより、4 がタグ [0] (バイト -128) に置き換えられます。

AuthorityKeyIdentifier のその前の 48、22 は、(構築された) SEQUENCE、長さ 22 バイトを意味します。

などなど

したがって、

キー識別子を計算して同じ配列を取得できますか?

はい、実際の KeyIdentifier OCTET STRING 値にドリルダウンします。

ある証明書が別の証明書の発行者であることを証明する別の方法はありますか

証明書の署名が、想定される発行者証明書に関連付けられた秘密鍵によって署名されているかどうかは、その証明書の公開鍵に対して検証することで確認できます。

PS:コメントの質問について

キー識別子の長さは常に 20 ですか? それは修正されていますか?ないかもしれませんね。

いいえそうではありません。前述のRFC 5280は次のように述べています。

For CA certificates, subject key identifiers SHOULD be derived from
the public key or a method that generates unique values.  Two common
methods for generating key identifiers from the public key are:

  (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
       value of the BIT STRING subjectPublicKey (excluding the tag,
       length, and number of unused bits).
  (2) The keyIdentifier is composed of a four-bit type field with
       the value 0100 followed by the least significant 60 bits of
       the SHA-1 hash of the value of the BIT STRING
       subjectPublicKey (excluding the tag, length, and number of
       unused bits).

Other methods of generating unique numbers are also acceptable.

あなたの CA は方法 1 (160 ビット = 20 バイト) を使用していると思いますが、これは単なる一般的な方法であり、明示的に推奨されるものではなく、必須ではありませんしたがって、いいえ、識別子の長さが 20 バイトであるとは期待できません。

PPS:コメントの質問について

署名は、ある証明書が別の証明書によって発行されたことを真に証明する唯一の方法ではありませんか?

これは、発行者と発行者の関係を証明するものでもありません。想定される発行者証明書に関連付けられた秘密鍵が、検査された証明書に署名したことを (少なくともある程度) 証明するだけですが、同じ秘密鍵と公開鍵のペアが存在する場合があります。複数の証明書で使用されます。

本質的に、複数の補完的なテストを実行する必要があり、それでも CA が奇妙なことをしないと信頼する必要があります。少し前に、Swisscom が CA 証明書の 1 つを変更して、追加の拡張機能または重要な属性を含めるようにしました (詳細を調べる必要があります。それらを証明する誰かがその変更を要求したと思います)。署名者証明書の所有者がその新しい拡張/重要な属性を認識していない場合でも、証明書は新しい CA 証明書によって発行されたように見えるようになりました。

結局のところ、現実の生活は、人が望むほど単純ではありません...

于 2013-07-26T09:50:12.410 に答える