我发现当我创建一个受密码保护的PKCS12文件时,该文件还包含受密码保护的私钥及其关联的公钥/证书,无论提供给{{1的密码如何,我都可以解密私钥。 (内部加密内容)只要为getKey()
的初始KeyStore
提供了正确的密码即可。这是一个已知问题还是有其他人看过这个?它看起来真的是私钥密码未被使用或一起被忽略。我使用Android和BouncyCastle作为提供者。我也很好奇这个问题是否适用于JKS而不仅仅是BouncyCastle?为清楚起见,删除了以下代码中的错误检查。
当我创建我的PKCS12文件时,我使用以下代码(load()
是privateKey
而RSAPrivateKey
是signedCert
):
X509Certificate
当我去加载PKCS12内容时,无论我为私钥密码添加什么,提取的私钥都被正确加载并且都是相同的(pkey1 == pkey2 == pkey3使用.equals()进行测试)。
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();
提前致谢!
答案 0 :(得分:4)
Bouncy Castle与许多其他提供商一样,忽略了PKCS#12的密钥密码。 PKCS#12是关于个人凭证交换的标准,其结果之一是大多数实现假设密钥库和密钥都只需要一个密码。
可以使用与用于密封密钥库的密码不同的密码在PKCS#12文件中加密密钥,但是如果执行此操作,则不太可能找到可以读取该文件的其他应用程序。或者换一种方式,尝试这不是一个疯狂的想法,只是KeyStore API和PKCS#12相似但不同,所以你会发现存在特性 - 在某些方面PKCS#12功能更全面,因为它允许附件以比KeyStore API更为通用的方式存储在文件中的对象的属性。
我们(如在Bouncy Castle中)最近试图提供一种更通用的方法来处理PKCS#12的单独API,这是目前的1.49测试版。如果你真的想要它,它将允许你使用不同的加密密码,但如果你希望你生产的文件被其他任何东西理解,我会建议不要使用它。 PKCS#12 API确实允许您更好地使用属性,但是这是否是您真正需要做的事情(通常您不需要),我将留给您决定。
你会发现像JKS这样的其他格式允许密钥和密钥库使用不同的密码。正如我之前提到的,不同之处在于,与PKCS#12不同,JKS并未被定义为“个人”存储机制。
此致
大卫