如何在 SpringBoot 中加载具有多个证书的 .keystore



>我正在开发Spring Boot Application v2.0。从我的 Spring 启动应用程序中,我正在发送 SOAP 请求以从 Soap WS 获取数据。我有多个 Soap 请求到不同的 Soap Web 服务。每个 Soap WS 都有自己的证书。我使用 Apache CXF v3.2.4 自动生成"ws client"类和 WS 的其他所有内容。

证书采用 PFX 格式。我已经通过keytool成功创建了密钥库。我尝试使用此代码设置 ssl.keyStore( 也不是设置这些值的好方法,我认为最好在应用程序属性中执行此操作...:

System.setProperty("javax.net.ssl.keyStore","path to my keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "mypassword");

我的密钥库中有 3 个不同的证书。所有这些都是单独测试的,如果它们在密钥库中只有一个,则它们都可以正常工作。问题是,当我在密钥库中有例如 3 个证书时,只加载列表中的第一个证书。

我在互联网上阅读了多篇文章,这篇文章最有趣,但不幸的是它没有解决我的问题(在 JVM 中注册多个密钥库(。

如果我按别名浏览证书链,我可以在控制台中看到所有证书。

String storename = "C:/Certificates/mykeystore.ks";
char[] storepass = "mypassword".toCharArray();
String alias = "myalias";
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(storename), storepass);             
java.security.cert.Certificate[] cchain = ks.getCertificateChain(alias);            
List mylist = new ArrayList();
for (int i = 0; i < cchain.length; i++) {                 
mylist.add(cchain[i]);
}
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertPath cp = cf.generateCertPath(mylist);
System.out.println(cp);

你有什么建议吗?!我应该怎么做才能实现一个密钥库与多个证书或任何工作加载的阶段? 提前谢谢。

附言我也试图通过Portecle将这些证书放在jdk/jre/lib/security/cacerts中,但没有效果。

对于每个 Web 服务,我认为您应该单独处理密钥库(和/或信任库(,并在 application.properties 文件中进行配置。下面是使用特定证书集实例化 URL 连接的套接字工厂的可行示例。

应用程序属性

keystore1.Path = src/main/resources/jks/yourKeyStoreFile1
keystore1.Password = keystore1pwd
truststore1.Path = src/main/resources/security1/cacerts
truststore1.Password = truststore1pwd
keystore2.Path = src/main/resources/jks/yourKeyStoreFile2
keystore2.Password = keystore2pwd
truststore2.Path = src/main/resources/security2/cacerts
truststore2.Password = truststore2pwd

当您使用不同的 Web 服务时,请使用不同的套接字工厂。下面是 .p12 密钥库和 .jks 信任库(证书(的示例。您可以轻松地将证书类型转换为不同的格式。

@Component
public class MySocketFactory {
@Value("${keystore1.Path}")
String keystore1Path;
@Value("${keystore1.Password}")
String keystore1Password;
@Value("${truststore1.Path}")
String truststore1Path;
@Value("${truststore1.Password}")
String truststore1Password;
public MySocketFactory() {
}
public SSLSocketFactory getSocketFactory() {
try {
SSLContext context = SSLContext.getInstance("TLS");
KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
char[] keyStorePassword = keystore1Password.toCharArray();
keyStore.load(new FileInputStream(keystore1Path), keyStorePassword);
keyMgrFactory.init(keyStore, keyStorePassword);
TrustManagerFactory trustStrFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore trustStore = KeyStore.getInstance("JKS");
char[] trustStorePassword = truststore1Password.toCharArray();
trustStore.load(new FileInputStream(truststore1Path), trustStorePassword);
trustStrFactory.init(trustStore);
context.init(keyMgrFactory.getKeyManagers(), trustStrFactory.getTrustManagers(), null);
return context.getSocketFactory();
} catch (Exception e) {
System.err.println("Failed to create a server socket factory...");
e.printStackTrace();
return null;
}
}
}

为第二个套接字工厂创建相同的代码。希望这有帮助。

相关内容

  • 没有找到相关文章

最新更新