以下代码:
//used Bouncy Castle provider for keyStore
keyStore.setKeyEntry(alias, (Key)keyPair.getPrivate(), pwd, certChain); 在certChain持有结束证书和发行者证书(即两个证书)的情况下,
如果keystore是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;
}发布于 2012-12-19 16:27:59
您的代码有两个错误:
first:您没有为证书设置颁发者(客户端证书应由CA颁发以建立有效的链)。
second:您在创建证书链时使用了错误的顺序(应该是客户端证书,最后是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-16 19:03:08
根据您使用的JDK,有不同的打包应用程序的方法。当一些人使用Linux和OpenJDK以及其他在Windows上使用SunJDK (Oracle)的开发时,就会发生这种情况。
最新的有一些额外的配置,以便能够使用最强大的算法。如果您的问题与JCE策略相关,This article可以帮助您。
https://stackoverflow.com/questions/13207378
复制相似问题