4

パスワードで保護された秘密鍵とそれに関連付けられた公開鍵/証明書も含むパスワードで保護された PKCS12 ファイルを作成すると、getKey()(内部の暗号化されたコンテンツ) に提供されたパスワードに関係なく、秘密鍵を復号化できることがわかりました。KeyStoreのイニシャルに正しいパスワードが提供されている限りload()。これは既知の問題ですか、それとも他の誰かがこれを見たことがありますか? 秘密鍵のパスワードが使用されていないか、まったく無視されているようです。BouncyCastle をプロバイダーとして Android を使用しています。この問題が BouncyCastle だけでなく、JKS にも当てはまるかどうかも知りたいです。以下のコードのエラー チェックは、わかりやすくするために削除されています。

PKCS12 ファイルを作成するときは、次のコードを使用します ( privateKeyis anRSAPrivateKeyおよびsignedCertis an X509Certificate):

KeyStore store;
store = KeyStore.getInstance( "PKCS12", "BC" );
store.load( null, null );

X509Certificate[] chain = new X509Certificate[1];
chain[0] = signedCert;

store.setKeyEntry( pkcs12Alias, privateKey, p12PkeyPass.toCharArray(), chain );

FileOutputStream fos;
File outputDir = appContext.getFilesDir();
File pkcs12File = new File( outputDir, p12Filename );
fos = new FileOutputStream( pkcs12File );

store.store( fos, p12Pass.toCharArray() );
fos.flush();
fos.close();

PKCS12 の内容を読み込もうとすると、秘密鍵のパスワードに何を入力しても、抽出された秘密鍵はすべて正しく読み込まれ、すべて同じです (.equals() でテストされた pkey1 == pkey2 == pkey3)。

FileInputStream fis;
KeyStore store;
File pkcs12File = new File( activity.getFilesDir(), p12Filename );
fis = new FileInputStream( pkcs12File );
store = KeyStore.getInstance( "PKCS12", "BC" );
store.load( fis, p12Pass.toCharArray() );

X509Certificate signedCert = (X509Certificate) store.getCertificate( pkcs12Alias );

// try to get the private key with different passwords - result is the same
RSAPrivateKey pkey1 = (RSAPrivateKey) store.getKey( pkcs12Alias, p12PkeyPass.toCharArray() );
RSAPrivateKey pkey2 = (RSAPrivateKey) store.getKey( pkcs12Alias, "".toCharArray() );
RSAPrivateKey pkey3 = (RSAPrivateKey) store.getKey( pkcs12Alias, "something completely different".toCharArray() );

fis.close();

前もって感謝します!

4

1 に答える 1

5

Bouncy Castle は、他の多くのプロバイダーと同様に、PKCS#12 のキー パスワードを無視します。PKCS#12 は、個人の資格情報の交換に関する標準です。この結果の 1 つは、ほとんどの実装では、キーストアとキーの両方に必要なパスワードは 1 つだけであると想定していることです。

キーストアを封印するために使用されるパスワードとは異なるパスワードを使用して、PKCS#12 ファイルでキーを暗号化することは可能ですが、これを行うと、ファイルを読み取ることができる別のアプリケーションが見つかる可能性は低くなります。別の言い方をすれば、これを試すのはクレイジーなアイデアではありません。KeyStore API と PKCS#12 は似ているが異なるというだけなので、特異性が存在することに気付くでしょう。 KeyStore API よりもはるかに一般的な方法で、ファイルに格納されているオブジェクトに属性を適用します。

(Bouncy Castle のように) 最近、1.49 の現在のベータ版である PKCS#12 用の別の API で、これを処理するためのより一般的な方法を提供しようとしました。必要に応じて別の暗号化パスワードを使用することもできますが、作成したファイルを他の人が理解できるようにしたい場合は、使用しないことをお勧めします。PKCS#12 API を使用すると、属性をより有効に活用できますが、それが本当に必要なことであるかどうか (多くの場合、そうでない場合もあります) は、皆さんの判断にお任せします。

JKS などの他の形式では、キーとキーストアに異なるパスワードを使用できることがわかります。前述したように、ここでの違いは、PKCS#12 とは異なり、JKS が「個人用」ストレージ メカニズムとして定義されていないことです。

よろしく、

デビッド

于 2013-03-07T12:28:52.873 に答える