我目前正在使用我编写的代码在 IBM Httpd 服务器的端口上安装 SSL 证书。代码安装证书如下:
创建一个受密码保护的 .p12 文件,其中包含私钥对象和最终实体证书(作为 1 个元素的 X509Certificate 数组传递)。
public static KeyStore createKeyStoreFromKeyAndCertChain(String encoding, String friendlyName, X509Certificate[] certChain, PrivateKey key, String password) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { KeyStore store = KeyStore.getInstance(encoding); store.load(null, null); store.setKeyEntry(friendlyName, key, password.toCharArray(), certChain); return store;
这会正确生成一个可使用 openssl 和 keytool 解析的 .p12 文件。
- 使用以下命令创建 .kdb 文件,将颁发者证书添加到 .kdb 文件,然后添加在步骤 1 中创建的 .p12 文件(包含私钥和最终实体证书)。
"C:\Program Files (x86)\IBM\HTTPServer2\java\jre\bin\ikeycmd.exe" -keydb -create -db "C:\Work\Certs\IBM certs\test.kdb" -pw 密码 -type cms -expire 60 -stash
"C:\Program Files (x86)\IBM\HTTPServer2\java\jre\bin\ikeycmd.exe" -cert -add -db "C:\Work\Certs\IBM certs\key1.kdb" -pw 密码 -label icacert -file "C:\renewcert\ica.cer" -trust enable
"C:\Program Files (x86)\IBM\HTTPServer2\java\jre\bin\ikeycmd.exe" -cert -add -db "C:\Work\Certs\IBM certs\key1.kdb" -pw 密码 -label rootcert -file "C:\renewcert\rootCert.cer" -trust enable
"C:\Program Files (x86)\IBM\HTTPServer2\java\jre\bin\ikeycmd.exe" -cert -import -db "C:\renewcert\certWithPvtKey.p12" -pw 密码 -target "C:\Work \Certs\IBM certs\httpdkey.kdb" -target_pw 密码 -target_type cms
这将创建一个 .kdb 文件。
- 更新 httpd.conf 文件中的虚拟主机指令以存储与新创建的 .kdb 文件对应的信息:
Listen 10.212.143.105:6042
<VirtualHost 10.212.143.105:6042>
SSLEnable
SSLProtocolDisable SSLv2
SSLServerCert ibmhttpdsslcert
KeyFile "C:\Work\Certs\IBM certs\key1.kdb"
SSLStashFile "C:\Work\Certs\IBM certs\key1.sth"
</VirtualHost>
用于标记 SSLServerCert 的标签与步骤 1 中用于创建 .p12 的友好名称相同。
证书可以通过我们的应用程序(使用基于 Java 的 SSL 证书发现)和 openssl 发现。
问题
我们现在需要从 .kdb 文件中导出原始 .p12。同样,使用以下命令:
"C:\Program Files (x86)\IBM\HTTPServer2\java\jre\bin\ikeycmd.exe" -cert -export -db "C:\Work\Certs\IBM certs\key1.kdb" -pw 密码 -label ibmhttpdsslcert -type cms -target "C:\Work\Certs\IBM certs\certChain.p12" -target_pw 密码 -target_type pkcs12
本质上发生的是,生成的 .p12 文件似乎已损坏并且无法使用以下代码进行解析:
public static void main(String[] args) throws Exception {
String password = "password";
// Read the .p12 and convert it to Java objects
FileInputStream fm = new FileInputStream(new File("C:\\Work\\Certs\\IBM certs\\certChain.p12"));
KeyStore ks = KeyStore.getInstance("PKCS12");
try {
ks.load(fm, password.toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Size- " +ks.size());
Enumeration aliases = ks.aliases();
while(aliases.hasMoreElements()){
String param = (String) aliases.nextElement();
System.out.println("Param- " +param);
}
KeyStore.ProtectionParameter protParam =
new KeyStore.PasswordProtection(password.toCharArray());
// Retrieve the key using the alias "IBMHttpdSSLCert"
KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
ks.getEntry("IBMHttpdSSLcert", protParam);
PrivateKey myPrivateKey = pkEntry.getPrivateKey();
Object pemObject = myPrivateKey;
// Write the key to file
JcaPEMWriter pemWriter = new JcaPEMWriter(new FileWriter(new File("C:\\Work\\pvtKey.pem")));
pemWriter.writeObject(pemObject);
pemWriter.close();
System.out.println("Pvt key- " +myPrivateKey);
fm.close();
}
发生的情况是密钥库的大小报告为零 (0),并且密钥库文件也无法使用 keytool 解析。然而,同样可以使用 openssl 解析,但我们不能将 openssl 捆绑到代码二进制文件中。
知道这是否是 IBM 的密钥库导出实现的一个已知错误?