为什么在Java中创建SSL套接字时出现错误“无法存储非私有密钥”?
问题内容:
我正在使用旧版本的IBM iSeries(IBM-i,i5OS,AS / 400等),并在O / S版本V5R3M0上使用Java 5
JVM(经典,而不是ITJ J9)。
简而言之,这是场景:
- 我使用Portecle 1.7创建了类型为JKS的密钥库(注意:我确实尝试将密钥库转换为JCEKS,但由于不支持的格式而被拒绝,因此JKS是iSeries机器的唯一选择(至少我使用的版本)。
- 然后,我创建了密钥对和CSR,并将CSR发送给Thawte进行签名。
- 我成功地使用PKCS#7格式从Thawte导入了签名证书,以导入整个证书链,其中包括我的证书,Thawte中介和Thawte服务器根目录。
这一切都按预期进行。
但是,当我运行JVM时,将其正确配置为指向商店并提供它的密码(我过去使用在Portecle中创建的用于测试的自签名证书来完成此操作),然后尝试在443上启动Web服务器,我收到以下安全异常:
java.security.KeyStoreException: Cannot store non-PrivateKeys
谁能告诉我我哪里出了问题,或者接下来我要检查什么?
问题答案:
无需使用临时密钥库,您可以在单个中处理所有内容SSLContext
。
您需要SSLContext
使用自定义来初始化您的自定义设置,X509KeyManager
而不是使用default给出的自定义设置KeyManagerFactory
。在此X509KeyManager
,chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
应根据从套接字获得的本地地址返回不同的别名。
这样,您就不必担心将私钥从一个密钥库复制到另一个,这甚至适用于不能从中提取(并因此复制)但仅使用私钥的密钥库类型,例如PKCS #11。