私の要件は、証明書と秘密鍵を組み合わせ、その後、PEMwriterを使用して、私はファイルをエクスポートする必要がすることです。
私は秘密鍵とCSRを生成するためにはBouncyCastleを使用しました。その後、私はCAにCSRを提出し、証明書を得ました。次のコードは、生成鍵ペアのためであります
KeyPair idPair = KeyPairGenerator.getInstance("RSA").genKeyPair();
PublicKey publicKey = idPair.getPublic();
PrivateKey privkey = idPair.getPrivate();
次のコードは、証明書を受信した.cerファイルにエクスポートするためのものです。
CertStore store = response.getCertStore();
Collection<? extends Certificate> certs = store
.getCertificates(null);
Certificate[] chain = new Certificate[certs.size()];
int i = 0;
for (Certificate certificate : certs) {
chain[i++] = certificate;
}
FileOutputStream os = new FileOutputStream("cert.cer");
os.write("-----BEGIN CERTIFICATE-----\n".getBytes("US-ASCII"));
os.write(Base64.encodeBase64(chain[0].getEncoded(), true));
os.write("-----END CERTIFICATE-----\n".getBytes("US-ASCII"));
os.close();
さて、私の目標は、私は、エクスポートされたファイルを開いたとき、私は/インストールするには、入力されたパスワードに促さ証明書を表示しなければならないです。私は本当にこの部分について困惑しています。以前私は、次のようにキーストアにパスワードを追加しました
KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
keyStore.load(null, null);
keyStore.setKeyEntry("mykey", (Key) keyPair.getPrivate(), "Password1!".toCharArray(), certz);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
keyStore.store(bout, "Password1!".toCharArray()); // this is the password to open the .p12
byte[] keystore = bout.toByteArray();
bout.close();
しかし、今、私はパスワードを使用して証明書を保護する必要があります。これさえ可能ですか?もしそうなら、どのようなファイル拡張子になりますか?そして、符号化部(PemWriter)に私を導いてください。感謝
次のコードは、証明書を受信した.cerファイルにエクスポートするためのものです。
CertStore store = response.getCertStore();
Collection<? extends Certificate> certs = store
.getCertificates(null);
Certificate[] chain = new Certificate[certs.size()];
int i = 0;
for (Certificate certificate : certs) {
chain[i++] = certificate;
}
Asides:あなたが変換するために、そのループを必要としないCollection
配列に、ただ一つの呼び出しは.toArray (new T[optionally_correct_size])
それを行います。一方、あなたが最初の要素だけを使用しているので、あなただけの、すべての配列を必要としませんCollection<T>.iterator().next()
。
もっと実質的に第三の一方で、多くの-間違いなくすべてではない-のPrivateKeyで行わ操作も正常に動作するために、完全な証明書チェーンだけでなく、葉/エンドエンティティ証明書を必要とします。例えば、いくつかの署名者は、チェーンなしで署名を計算するが、いくつかの場合、または署名が検証できないので、それを受信したどんなによって拒否されることを状況にすることができます。あなたは何で、どのようなエクスポートされたファイル(複数可)のためには、どのように使用するか、何の手がかりを与えていないので、この上の任意のアドバイスを与えることは不可能です。フルチェーンがあればとされる必要な、それはまた、あなただけの個人/個別のPEMの本命や他の必要性何かのシーケンスを使用できるかどうかによって異なります。
私が何かわからないBase64
、使用しているエンコーダと、その署名ははBouncyCastleのものと一致しません。私はそれが正しく改行を生成したいと考えています。PEM形式は、単にBEGINライン、BASE64、END-ラインをされていません。それは、BEGIN-ラインをBASE64で改行して、END-ライン。いくつかのソフトウェアは、動作します時々でも改行せずに、しかし、いくつかのソフトウェアは、時々 、失敗します。参照してください。終了間際のRFC 7468秒2を。
さて、私の目標は、私は、エクスポートされたファイルを開いたとき、私は/インストールするには、入力されたパスワードに促さ証明書を表示しなければならないです。...しかし、今、私はパスワードを使用して証明書を保護する必要があります。これさえ可能ですか?
あなたはのPrivateKeyと証明書(複数可)を区別する必要があります。重要な方法に関連しますが、これらは異なるものであり、証明書は、公開できるように設計されている間のPrivateKeyは、プライベート/秘密なるように設計されています。誰もがそれを表示し、公開鍵操作のためにそれを使用します(暗号化または検証)と、それ以外の場合と同じように彼らは何を行うことができますので、具体的には、PEM形式の証明書は、暗号化されていません。
通常-しかし、PrivateKeyの操作(復号化または符号)を実行するために、あなたはのPrivateKeyが必要にリンクされている上記のように証明書またはチェーン-とのPrivateKeyができ、パスワードで暗号化された(少なくとも)にある二つの異なるので、慣例PEMフォーマットの方法それは「オープン」にパスワードを要求します。1990年代のOpenSSLバック事実上、そのいくつかのために使用することができるPEM暗号化方式定義「レガシー」または「伝統的な」こうして、BEGINラインにPEM型の各アルゴリズムについて異なるPrivateKeyのフォーマット、および示されたが-----BEGIN RSA PRIVATE KEY-----
、-----BEGIN DSA PRIVATE KEY-----
、-----BEGIN EC PRIVATE KEY-----
、などその後PKCS8がための汎用のPrivateKeyのフォーマットを定義し、すべてので指定された暗号化された変種を含めたJava暗号(JCA)を含む多くの他のソフトウェアで使用されるアルゴリズム、-----BEGIN ENCRYPTED PRIVATE KEY-----
(何のアルゴリズム名をメモしていません)。PKCS8バージョンは、(のみ)で、公式なされているRFC7468秒11。(他にも、非常に異なるPEMのようなOpenSSHの、パテ、およびPGPで使用privatekeysためのフォーマットもありますが、それらのどれもX.509タイプの証明書を使用しない。GnuPGは今PGPやS / MIMEの両方を実装し、使用Xをしていますが0.509 / PKIX S / MIMEのための。あなたはこれらのことに興味があるなら、そこSO上の多数の既存のQsがあり、かつsecurity.SXまたはcrypto.SXにいくつかの。)bcpkix
OpenSSLのレガシーフォーム実装と)PKCS8形式(複数可。(JavaははBouncyCastle実装PKCS8だけではなしに暗号化されず。)
同様に、「レガシーのJavaキーストア(JKSおよびJCEKS)パスワード暗号化のPrivateKey(S)ではなく、証明書(複数可)。PKCS12標準は、実際には非常に柔軟な(かつ複雑な)ですが、通常は実装されている(あなたのBC-ストアの例を含む)は、PrivateKeyの(S)のための強力なパスワード暗号化を使用し、証明書(複数可)のために非常に弱く壊れやすいパスワードの暗号化。これはどのようなセキュリティ上の利点を提供せずに不便であるので、私は、かなり確実なぜ行ったことがありません。
もしそうなら、どのようなファイル拡張子になりますか?
それはあなたまでほとんどだ、またはこれらのファイル誰のためのものである(誰がいる場合)。それははるかに便利であるため、人々は通常、そうするが、標準的には、ファイルの内容またはその逆に一致するように、ファイルの拡張子を必要としません。正式.cer
であると考えられるDERの証明書、およびRFC7468秒5.3 をお勧めします使用して.crt
PEMの証明書。あなたが別のファイルにキーを記述する場合、それを使用することはかなり一般的であるように思わ.key
または.pem
これを指定して、私はノー標準(と確かにIANA登録)を知っています。(RFC5958レジスタ.p8実際には何のためにDER PKCS8暗号化されていないとRFC8351レジスタDER PKCS8指定せずに暗号化された任意の拡張子を。)あなたは、キーと証明書(複数可)を記述する場合に同じすべてのプログラムが行うPEM形式のサポートではなく、ファイルには、私も以外の一般的な方法を見ていません.pem
。
だから、クラスパスにbcpkix、最終的にあなたの質問に取得:-)を考えると、あなたのプロバイダリスト(およびクラスパス)でBCプロバイダを持っている、そしてPrivateKey
オブジェクトでkv
:
import org.bouncycastle.openssl.PKCS8Generator;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPKCS8Generator;
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder;
import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder;
import org.bouncycastle.util.io.pem.PemWriter;
// for the OpenSSL legacy form
JcaPEMWriter x = new JcaPEMWriter (new OutputStreamWriter(System.out)); // or whatever
x.writeObject(kv, new JcePEMEncryptorBuilder("DES-EDE3-CBC").build("password".toCharArray()) );
// can substitute AES-{128,192,256}-CBC if desired, for more see source
x.close(); // or flush to keep underlying writer/stream
// for the PKCS8 form
PemWriter y = new PemWriter (new OutputStreamWriter(System.out)); // or whatever
y.writeObject(new JcaPKCS8Generator (kv, new JceOpenSSLPKCS8EncryptorBuilder(
PKCS8Generator.DES3_CBC).setPasssword("password".toCharArray()).build() ) );
// or AES_{128,192,256}_CBC, others will use PBES1 which is deprecated
y.close(); // or flush to keep underlying writer/stream