2013-03-07 33 views
3

我发现当我创建一个密码保护的PKCS12文件时,它还包含受密码保护的私钥及其关联的公钥/证书,我能够解密私钥,无论提供给getKey()(内部加密内容)的密码如何,只要为KeyStore的初始load()提供了正确的密码即可。这是一个已知问题还是有其他人看到这个?它看起来好像私钥密码未被使用或者一起被忽略。我使用Android和BouncyCastle作为提供者。我也很好奇这个问题对于JKS来说是否属实,而不仅仅是BouncyCastle?为清楚起见,在下面的代码中检查错误已被删除。KeyStore没有在BouncyCastle中应用/强制安装PKCS12文件的私钥密码

当我创建我的PKCS12文件我用下面的代码(privateKeyRSAPrivateKeysignedCertX509Certificate):

KeyStore store; 
store = KeyStore.getInstance("PKCS12", "BC"); 
store.load(null, null); 

X509Certificate[] chain = new X509Certificate[1]; 
chain[0] = signedCert; 

store.setKeyEntry(pkcs12Alias, privateKey, p12PkeyPass.toCharArray(), chain); 

FileOutputStream fos; 
File outputDir = appContext.getFilesDir(); 
File pkcs12File = new File(outputDir, p12Filename); 
fos = new FileOutputStream(pkcs12File); 

store.store(fos, p12Pass.toCharArray()); 
fos.flush(); 
fos.close(); 

当我去加载PKCS12内容,不管是什么,我把对私钥密码,提取的私钥全部正确加载并且全部相同(pkey1 == pkey2 == pkey3使用.equals()进行测试)。

FileInputStream fis; 
KeyStore store; 
File pkcs12File = new File(activity.getFilesDir(), p12Filename); 
fis = new FileInputStream(pkcs12File); 
store = KeyStore.getInstance("PKCS12", "BC"); 
store.load(fis, p12Pass.toCharArray()); 

X509Certificate signedCert = (X509Certificate) store.getCertificate(pkcs12Alias); 

// try to get the private key with different passwords - result is the same 
RSAPrivateKey pkey1 = (RSAPrivateKey) store.getKey(pkcs12Alias, p12PkeyPass.toCharArray()); 
RSAPrivateKey pkey2 = (RSAPrivateKey) store.getKey(pkcs12Alias, "".toCharArray()); 
RSAPrivateKey pkey3 = (RSAPrivateKey) store.getKey(pkcs12Alias, "something completely different".toCharArray()); 

fis.close(); 

在此先感谢!

回答

4

Bouncy Castle和许多其他提供商一样忽略了PKCS#12的密钥密码。 PKCS#12是关于个人证书交换的标准,其结果是大多数实现假定密钥库和密钥都只需要一个密码。

可能在PKCS#12文件中使用不同密码加密密钥,以便密封密钥库,但是如果您这样做,则不太可能找到可以读取该文件的其他应用程序。换句话说,尝试这不是一个疯狂的想法,只是KeyStore API和PKCS#12是相似但不同的,所以你会发现存在特质 - 在某些方面,PKCS#12更加全面,因为它允许附件以比KeyStore API更通用的方式将属性存储到文件中存储的对象。

我们(和Bouncy Castle一样)最近试图提供一种更通用的方法来在PKCS#12的单独API中处理此问题,该API在1.49的当前测试版中。如果你真的想要,它可以让你使用不同的加密密码,但如果你希望你生成的文件能够被其他人理解,我会建议你不要这样做。 PKCS#12 API允许您更好地使用属性,但是否这是您真正需要做的事情(通常您不会),我会留给您决定。

你会发现像JKS这样的其他格式允许为密钥和密钥库使用不同的密码。正如我之前提到的,这里的区别在于JKS并不像PKCS#12那样被定义为“个人”存储机制。

问候,

大卫

+0

谢谢!我使用BC 1.47。关于您的评论,您是否认为1.49版可以解决与PKCS12包属性相关的以下问题? [在Android中使用BouncyCastle PKCS12SafeBagBuilder或PKCS12BagAttributeCarrier更改PKCS12安全包属性?](http://stackoverflow.com/questions/12890436/use-bouncycastle-pkcs12safebagbuilder-or-pkcs12bagattributecarrier-to-change-pkc) – aspergillusOryzae 2013-03-11 21:32:10

+0

是的。我已经添加了一个解决这个问题的答案,但简短的答案是org.bouncycastle.pkcs包提供了处理这些问题的最一般方法。 – 2013-03-12 23:23:13

相关问题