java - 如何为 HTTPS 调用指定出站证书别名?

标签 java ssl https certificate keystore

我正在调用需要客户端证书身份验证的网络服务。

如果我指定包含单个证书(服务期望的客户端证书)的 Java keystore ,则一切正常。但是,如果我使用包含多个证书的 keystore ,那么我似乎无法指定客户端应该选择哪个证书,客户端似乎会选择第一个可用的证书(按字母顺序排列)。

我尝试了以下属性,但没有预期的结果:

System.setProperty("com.sun.enterprise.security.httpsOutboundKeyAlias", "my-client-certificate alias");

如何指定应使用的客户端证书别名?

最佳答案

Jakub 的链接提供 in his response带你找到答案,但我想在这里发布一个更简单的回复,因为我们在这个问题上苦苦挣扎了很长一段时间才最终得到了有效的解决方案。

我们有这样的情况,有多个证书可供使用,我们需要使用具有特定别名的证书来执行我们的连接。为此,我们创建了自己的 KeyManager 实现,该实现将其大部分功能传递给默认的 X509KeyManager,但具有在执行连接时准确选择要使用的正确别名的功能。

首先是我们创建的 key 管理器:

public class FilteredKeyManager implements X509KeyManager {

private final X509KeyManager originatingKeyManager;
private final X509Certificate[] x509Certificates;

public FilteredKeyManager(X509KeyManager originatingKeyManager, X509Certificate[] x509Certificates) {
    this.originatingKeyManager = originatingKeyManager;
    this.x509Certificates = x509Certificates;
}

public X509Certificate[] getCertificateChain(String alias) {
    return x509Certificates;
}

public String[] getClientAliases(String keyType, Principal[] issuers) {
    return new String[] {"DesiredClientCertAlias"};
}

实现所需的所有其他方法都传递给 originatingKeyManager

然后,当我们实际设置上下文时:

SSLContext context = SSLContext.getInstance("TLSv1");
context.init(new KeyManager[] { new FilteredKeyManager((X509KeyManager)originalKeyManagers[0], desiredCertsForConnection) },
    trustManagerFactory.getTrustManagers(), new SecureRandom());

希望这能说明问题,并适用于任何其他试图解决此问题的人。

关于java - 如何为 HTTPS 调用指定出站证书别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5292074/

相关文章:

nginx - Nginx反向代理背后的Nginx配置

java - Gradle - 在单元测试中使用其他版本的依赖

java - 为 TextView 创建简单的文本弹出窗口

ios - 将使用android_studio制作的android应用程序转换为IOS

java - 如何监视应用程序日志中的 java 堆内存不足错误?

SSL Pinning 和证书到期

ios - 获取 iOS 中包含的可信根证书的 PEM 文件(用于验证 gRPC)

ssl - 从 cloudflare 添加 SSL 后域无法解析

c# - SSL 自签名证书

.htaccess - 在我的重写和规则 .htaccess 文件上强制使用 HTTPS