具有多个密钥和不同密码的Java密钥库

时间:2016-02-29 20:54:03

标签: java ssl networking

我创建了一个java JKS keytore:

keytool -genkey -alias mydomain -keyalg RSA -keystore mytest.jks -keysize 2048

之后我创建了一个P12文件,使用服务器的CRT和openssl:

openssl pkcs12 -export -in server.crt -inkey server.key > server.p12

现在我将P12文件导入到我之前创建的JKS密钥库中:

keytool -importkeystore -srckeystore server.p12 -destkeystore mytest.jks -srcstoretype pkcs12

它可以工作,我可以使用此JKS初始化到服务器的SSL连接:

public static SSLContext initSSLContext(String keystoreLocation, String keystorePwd, String truststorePwd, String serverCrtPwd)
SSLContext context;
context = SSLContext.getInstance("TLS");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keystoreLocation), keystorePwd.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, serverCrtPwd.toCharArray());

KeyStore trustStore = KeyStore.getInstance("jks");
trustStore.load(new FileInputStream(keystoreLocation), truststorePwd.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);

context.init(kmf.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());

将导入的CRT文件的密钥库位置,密码和密码放在它运行的参数中。

现在我必须将多个P12文件转换并导入到同一个JKS密钥库中,多次运行导入部分,我有多个密钥导入了不同的别名,当然还有不同的密码。我的问题是,现在每个导入的密钥都有自己的密码。 我想用给定密钥库中的每个可用别名初始化一次SSL连接。因为更多服务器将使用SSL将数据发送到我的应用程序,它们具有不同的密码,它们被导入到我的密钥库但是我无法使用多个密码初始化我的密钥库,它只接受一个密码。如何使用具有不同别名和不同密码的多个导入的P12初始化我的密钥库? init方法只接受“从密钥库恢复密钥”的一个参数。

谢谢!

1 个答案:

答案 0 :(得分:0)

最近我遇到了同样的挑战来实现这一目标。在寻找解决方案时,我遇到了您的问题。也许我晚了 5 年,但在找到解决方案后,我想与您分享。

所以我发现你有几个选择:

  • 所有的密钥都应该有相同的密码,或者
  • 为每个键实例化一个单独的 SSLContext 和它自己的 KeyManager,或者

显然您已经知道这些选项并且您不想执行这些操作。另一种方法是仍然拥有具有不同密钥和密码的密钥库。假设您有一个密钥库,其中包含具有以下别名和密码的密钥:

  • foo -> foo-password
  • bar -> bar-password
  • lorum-ipsum -> lorum-ipsum-password

以下设置将为您解决问题:

var sslContext = SSLContext.getInstance("TLS");
var keyStore = ... // your custom KeyStore

var keyManager = KeyManagerUtils.createKeyManager(keyStore, Map.of(
        "foo","foo-password".toCharArray(),
        "bar","bar-password".toCharArray(),
        "lorum-ipsum","lorum-ipsum-password".toCharArray()
));

sslContext.init(new KeyManager[]{keyManager}, trustManagers, null);

这个 KeyManagerUtils 在幕后所做的是为每个密钥/密码创建一个 KeyManager 并将其合并到一个基本 KeyManager 中,该基 KeyManager 能够包含多个 KeyManager 并将其作为单个返回,以便您可以在 SSLContext 中使用它.有关详细信息和用法,请参见此处:Github - SSLContext-Kickstart