8

S/MIME メール (もともと Outlook 経由で送信されたもの) を復号​​化しようとしています。そのために、bouncycastle API を使用しています。しかし、私は思わぬ障害に遭遇しています。

Windows 証明書ストアに、受信者の証明書があります。私は以前、署名付きで暗号化された電子メールを相手方に送信するためにそれを使用していました。次に、証明書 (秘密鍵付き) を .pfx ファイルとしてエクスポートし、この pfx ファイルを Java KeyStore にロードしました。しかし、それは機能しません。これは、サブジェクトのキー識別子が一致しないためだと思われます。

KeyStore からサブジェクト キー ID を取得するために使用しているコードは次のとおりです。

KeyStore ks = KeyStore.getInstance("PKCS12");
char[]   pw = "password".toCharArray();

ks.load(new FileInputStream("d:\\cert_priv_key.pfx"), pw);

Enumeration en = ks.aliases();

while( en.hasMoreElements() )
{
    String alias = (String)en.nextElement();
    System.out.println(alias);

    if( ks.isKeyEntry(alias) )
    {
        Certificate[]   chain = ks.getCertificateChain(alias);
        X509Certificate cert  = (X509Certificate)chain[0];

        byte[] id = cert.getExtensionValue("2.5.29.14");

        System.out.println("  " + toHex(id));
    }
}

これにより、次のキー識別子が出力されます。

04 16 04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

ただし、Windows 証明書ストアを確認すると、キー識別子が異なります。

88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

KeyStore は前に余分な 4 バイトを返します (対象のキー識別子は、キーの 160 ビット SHA1 ハッシュである必要があるため、長さは 20 バイトですよね?)。

さらに紛らわしいのは、bouncycastle API を使用して S/MIME 電子メールを解析し、受信者 ( SMIMEEnveloped.getRecipientInfos().getRecipients()) を調べると、返された唯一の受信者 (1 つだけである必要があります) がこのサブジェクト キー識別子を持っているという事実です。

04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

...余分なバイトは4バイトではなく2バイトだけです。これが、証明書で電子メールを復号化できない理由だと思います。

これらのサブジェクト キー識別子がどれも一致しないのはなぜですか? 私は何を間違っていますか?

4

3 に答える 3

17

すべての仕様を理解していれば、これらの答えはすべて一貫していますが、もちろん、そうでない場合は混乱を招くことになります。最初に確認する場所は、RFC 5280 のセクション 4.2.1.2です。この場合、(1)の方法が使われます。次に、セクション A.2の KeyIdentifier の定義を見てください。これは、OCTET STRING として定義されます。ここで、ASN.1 OCTET STRING をどのようにエンコードするかを見てください。これは、16 進数の 04 で始まり、その後にバイト単位の長さ (20 バイトまたは 14 hex) が続き、その後に実際のオクテット文字列 (SHA1 ハッシュ) が続きます。したがって、拡張機能の内容は

04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

最後に、 Extensionの ASN.1 定義を見てください。拡張値は OCTET STRING としてエンコードする必要があると書かれています。この特定の拡張の場合、正味の効果は、OCTET STRING として連続して 2 回エンコードされることです。このレベルでは、OCTET STRING は 2 つのヘッダー バイトを含む前の OCTET STRING である04 14ため、長さは 16 進数の 16 であり、エンコーディングは次のとおりです。

04 16 04 14 88 ed bb 7c 64 7b 41 63 48 0a 24 40 2b 3c d0 78 72 3c 30 b3

これは、 X509Extension.getExtensionValue()メソッドによって返される値です。キー ID の興味深い部分は で始まる SHA1 ハッシュ88なので、これが Windows ユーティリティに表示されます。明らかに、使用している bouncycastle メソッドは、追加のデコードを行わずに拡張​​子を表示します。

于 2011-06-30T01:21:15.227 に答える
1

S/MIME メッセージは Outlook 2010 で作成されたものですか?

その場合は、http: //bouncy-castle.1462172.n4.nabble.com/Re-ReadEncryptedMail-sample-and-SubjectKeyIdentifier-instead-of-IssuerSerial-Outlook-2010-Hack-td3042968.htmlおよびhttps://bugzillaを参照してください。詳細については、.mozilla.org/show_bug.cgi?id=559243

マーティン・ブリンカーズ

于 2011-06-30T10:14:42.143 に答える