将证书链保存在pkcs12密钥库中 [英] Saving certificate chain in a pkcs12 keystore

查看:217
本文介绍了将证书链保存在pkcs12密钥库中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码:

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

其中certChain持有结束证书和发行人证书(即两个证书),
$ b如果keyStore是 PKCS12 的实例,$ b不会将发行者证书保存为保存到文件系统密钥库文件中的链的一部分。

where certChain holds the end certificate and the issuer certificate (i.e. two certificates),
doesn't save the issuer certificate as part of the chain in the saved to the file system keystore file if the keyStore is an instance of PKCS12.

如果密钥库类型为 PKCS12-3DES-3DES ,它会保存两个证书。
这是为什么?不是PKCS12假设两个证书都是链的一部分吗?

It does save both certificates if the keystore type is PKCS12-3DES-3DES. Why is this? Doesn't a PKCS12 suppose to have both certificates are part of the chain?

编辑:这是 SSCCE 。这适用于JKS,失败并带有PKCS12:只有链中的第一个证书可以通过 getCertificateChain(字符串)。可以使用 openssl pkcs12 打开保存的文件,显示两个证书。

Here's an SSCCE. This works fine with "JKS", fails with "PKCS12": Only the first certificate in the chain is accessible via getCertificateChain(String). The saved file can be opened with openssl pkcs12 revealing both certificates.

    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;
}


推荐答案

您的代码有2个错误:

Your code has 2 error:

优先:您没有为证书设置Issuer(CA应颁发客户端证书以生成有效链)。

first: You not set Issuer for certificate (client cert should be issued by CA to make valid chain).

第二名:创建证书链时使用错误的订单(应该是客户ferts,CA last)

second: You use wrong order when create certificate chain (should be client ferts, CA last)

这里是重写的SSCCE,它没有错误。

here is reworked SSCCE, and it works without errors.

@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.setIssuerDN(new X509Name(dn));
        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;
    }

这篇关于将证书链保存在pkcs12密钥库中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆