23

次のコード:

//used Bouncy Castle provider for keyStore
keyStore.setKeyEntry(alias, (Key)keyPair.getPrivate(), pwd, certChain);  

ここで、certChain は終了証明書と発行者証明書 (つまり 2 つの証明書) を保持し
ますPKCS12

キーストア タイプが の場合、両方の証明書が保存されますPKCS12-3DES-3DES。どうしてこれなの?PKCS12 は、両方の証明書がチェーンの一部であると想定していませんか?

編集:これはSSCCEです。これは で正常に動作し"JKS"、 で失敗します"PKCS12": チェーンの最初の証明書のみが 経由でアクセスできますgetCertificateChain(String)openssl pkcs12保存されたファイルは、両方の証明書を表示して開くことができます。

    public void testKeyStore() {
    try {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        Certificate[] outChain = { createCertificate("CN=CA", publicKey, privateKey), createCertificate("CN=Client", publicKey, privateKey) };

        KeyStore outStore = KeyStore.getInstance("PKCS12");
        outStore.load(null, "secret".toCharArray());
        outStore.setKeyEntry("mykey", privateKey, "secret".toCharArray(), outChain);            
        OutputStream outputStream = new FileOutputStream("c:/outstore.pkcs12");
        outStore.store(outputStream, "secret".toCharArray());
        outputStream.flush();
        outputStream.close();

        KeyStore inStore = KeyStore.getInstance("PKCS12");      
        inStore.load(new FileInputStream("c:/outstore.pkcs12"), "secret".toCharArray());
        Key key = outStore.getKey("myKey", "secret".toCharArray());
        assertEquals(privateKey, key);

        Certificate[] inChain = outStore.getCertificateChain("mykey");
        assertNotNull(inChain);
        assertEquals(outChain.length, inChain.length);
    } catch (Exception e) {
        e.printStackTrace();
        fail(e.getMessage());
    }
}

private static X509Certificate createCertificate(String dn, PublicKey publicKey, PrivateKey privateKey) throws Exception {
    X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
    certGenerator.setSerialNumber(new BigInteger("1"));
    certGenerator.setIssuerDN(new X509Name(dn));
    certGenerator.setSubjectDN(new X509Name(dn));
    certGenerator.setNotBefore(Calendar.getInstance().getTime());
    certGenerator.setNotAfter(Calendar.getInstance().getTime());
    certGenerator.setPublicKey(publicKey);
    certGenerator.setSignatureAlgorithm("SHA1withRSA");
    X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC");
    return certificate;
}
4

2 に答える 2

17

あなたのコードには2つのエラーがあります:

最初:証明書の発行者を設定しません (有効なチェーンを作成するには、CA によってクライアント証明書が発行される必要があります)。

2番目:証明書チェーンを作成するときに間違った順序を使用します(クライアント証明書、CAが最後である必要があります)

これは SSCCE を作り直したもので、エラーなく動作します。

@Test
public void testKeyStore() throws Exception{
        try {
        String storeName =  "/home/grigory/outstore.pkcs12";
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        Certificate trustCert =  createCertificate("CN=CA", "CN=CA", publicKey, privateKey);
        Certificate[] outChain = { createCertificate("CN=Client", "CN=CA", publicKey, privateKey), trustCert };

        KeyStore outStore = KeyStore.getInstance("PKCS12");
        outStore.load(null, "secret".toCharArray());
        outStore.setKeyEntry("mykey", privateKey, "secret".toCharArray(), outChain);
        OutputStream outputStream = new FileOutputStream(storeName);
        outStore.store(outputStream, "secret".toCharArray());
        outputStream.flush();
        outputStream.close();

        KeyStore inStore = KeyStore.getInstance("PKCS12");
        inStore.load(new FileInputStream(storeName), "secret".toCharArray());
        Key key = outStore.getKey("myKey", "secret".toCharArray());
        Assert.assertEquals(privateKey, key);

        Certificate[] inChain = outStore.getCertificateChain("mykey");
        Assert.assertNotNull(inChain);
        Assert.assertEquals(outChain.length, inChain.length);
    } catch (Exception e) {
        e.printStackTrace();
        throw new AssertionError(e.getMessage());
    }
   }
    private static X509Certificate createCertificate(String dn, String issuer, PublicKey publicKey, PrivateKey privateKey) throws Exception {
        X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
        certGenerator.setSerialNumber(BigInteger.valueOf(Math.abs(new Random().nextLong())));
        certGenerator.setSubjectDN(new X509Name(dn));
        certGenerator.setIssuerDN(new X509Name(issuer)); // Set issuer!
        certGenerator.setNotBefore(Calendar.getInstance().getTime());
        certGenerator.setNotAfter(Calendar.getInstance().getTime());
        certGenerator.setPublicKey(publicKey);
        certGenerator.setSignatureAlgorithm("SHA1withRSA");
        X509Certificate certificate = (X509Certificate)certGenerator.generate(privateKey, "BC");
        return certificate;
    }
于 2012-12-19T08:27:59.110 に答える
0

使用する JDK に応じて、アプリケーションをパッケージ化する方法が異なります。Linux と OpenJDK を使用している一部の人々や、SunJDK (Oracle) を使用して Windows で開発している他の人々がいるときに、私たちに起こります。

最新のものには、最強のアルゴリズムを使用できるようにするために、追加の構成が必要です。この記事は、問題が JCE ポリシーに関連している場合に役立ちます。

于 2012-12-16T11:03:08.100 に答える