Jakub在他的回复中提供的链接将引导您找到答案,但我想在这里发布一个更简单的回复,因为我们在最终获得有效的东西之前,已经为这个问题挣扎了很长一段时间。
我们的情况是,有多个证书可供使用,我们需要使用具有特定别名的证书来执行连接。我们通过创建自己的KeyManager实现来实现这一点,该实现将其大部分功能传递给默认的X509KeyManager,但具有在执行连接时准确选择要使用的正确别名的功能。
首先是我们创建的密钥管理器:
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());
希望这能说明问题,并为其他任何试图解决这个问题的人工作。