14

私は最近、Apple 製品 (iPhone 構成ユーティリティ) の Java でのモックアップを担当しています。私が少し行き詰まっているセクションの 1 つは、Exchange ActiveSync に関する部分です。そこで、キーチェーンから証明書を選択して、EAS アカウントの資格情報として使用できます。調査の結果、実際には PKCS12 キーストアを作成し、選択した証明書の秘密鍵を挿入し、それを XML にエンコードしていることがわかりました。これまでのところ大したことではありません。キーチェーン アクセスで .p12 ファイルを作成すると、問題なくアップロードされます。しかし、それをJavaに持ち込もうとすると問題が発生します。

以前に .p12 ファイルで使用した証明書の 1 つを .cer ファイルとしてエクスポートするとします (これは、環境で取得することを期待しているものです)。これをJavaにアップロードすると、次のようにCertificateオブジェクトを取得します...

KeyStore ks = java.security.KeyStore.getInstance("PKCS12");
ks.load(null, "somePassword".toCharArray());

CertificateFactory cf = CertificateFactory.getInstance("X.509", new BouncyCastleProvider());
java.security.cert.Certificate userCert  = cf.generateCertificate(new FileInputStream("/Users/me/Desktop/RecentlyExportedCert.cer"));

でもやってみると…

ks.setCertificateEntry("SomeAlias", userCert);

私は例外を取得します...

java.security.KeyStoreException: TrustedCertEntry not supported

したがって、証明書からキーに移動します。しかし、これらの証明書 (私は CA 証明書も取得しました) を使用すると、秘密鍵ではなく公開鍵にしかアクセスできません。そして、そのように公開鍵を追加しようとすると...

java.security.cert.Certificate[] chain = {CACert};
ks.setKeyEntry("SomeAlias", userCert.getPublicKey().getEncoded(), chain);

私は...

java.security.KeyStoreException: Private key is not stored as PKCS#8 EncryptedPrivateKeyInfo: java.io.IOException: DerValue.getOctetString, not an Octet String: 3

だから今、私はここにいます。秘密鍵を.cerファイルからJavaのPKCS12キーストアに取得する方法を知っている人はいますか? 私は正しい軌道に乗っていますか?

前もって感謝します!

4

2 に答える 2

18

PKCS#12 形式は、証明書チェーンに関連付けられた秘密鍵を格納することを目的としており、両方が必要です (チェーン全体は必要ないかもしれませんが)。PKCS12キーストア タイプは、この形式を Java にマッピングするのに適していKeyStoreますが、この理由ですべてがサポートされているわけではありません。

最初の試行でやろうとしていることは、証明書を単独で保存することですが、うまくいきません。

2 回目の試行 ( ) で行おうとしているks.setKeyEntry("SomeAlias", userCert.getPublicKey().getEncoded(), chain)のは、秘密鍵であるべきものの代わりに公開鍵を取得することです (「 」を参照KeyStore#setKeyEntry)。

.cerファイルは、秘密鍵ではなく証明書専用である傾向があります (ただし、もちろん、拡張子は最終的には単なる目安です)。Keychain Access.app.cerからファイルをエクスポートすると、秘密鍵は取得されません (エクスポート形式はそのためです)。.p12

KeychainStore に関する編集:

この変換を行おうとしている理由が、最終的にキーチェーンに既に存在する秘密鍵と証明書にアクセスすることである場合は、それらをKeychainStore直接次からロードできます。

KeyStore ks = KeyStore.getInstance("KeychainStore", "Apple");
ks.load(null, "-".toCharArray());

これに関するいくつかの注意事項:

  • "-".toCharArray()OS のセキュリティ サービスによって (他のアプリケーションと同様に) アクセスが要求されるため、null や空でないパスワードは秘密鍵 (例: ) を使用します。
  • 私の知る限り、まだバグがあり、1 つの秘密鍵/証明書のペアにしかアクセスできません(秘密鍵/証明書のペアのペアがキーチェーンに多数存在する場合でも)。
于 2010-09-01T01:20:04.323 に答える
3

http://www.docjar.com/html/api/org/bouncycastle/jce/examples/PKCS12Example.java.html

これは、関連付けられた秘密鍵を持つ証明書を PKCS12 キーストアに追加する方法です。クライアント認証を使用している場合、キーストアには秘密鍵も含まれている必要があります。その場合は、KeyStore.getInstance("PKCS12") を使用します。

クライアント認証を使用せず、サーバー認証のみを使用している場合 (秘密鍵はサーバーに属しているため、キーストアに追加されません)、KeyStore.getInstance("JKS") を使用することをお勧めします。その 1 つのキーストアへのエイリアス。

PKCS12 を使用している場合、私が知る限り、その証明書に使用する秘密鍵に関連付けられた証明書を 1 つだけ追加できます (証明書チェーン全体を追加する必要があります)。

于 2010-11-30T08:17:56.080 に答える