java - 在连接之前,我如何告诉 SSLSocket 所需的 key 输入的别名?

标签 java ssl keystore authentication

我在 Java keystore 中有两个证书/ key 对。这些键条目的别名是“foo”和“bar”。

我的 TLS 客户端(java 程序)使用 keystore 。 TLS 客户端身份验证在连接打开期间完成。 当 TLS 服务器向客户端请求证书时,客户端程序应使用“foo”键输入。 现在,客户端在连接握手期间向服务器发送了错误的证书(“bar”)。

在连接之前我如何告诉 SSLSocket 所需的 key 输入的别名?

目前代码如下:

final SSLSocket ss = (SSLSocket)SSLSocketFactory.getDefault().createSocket(); 
ss.setEnabledProtocols( new String[] {"TLSv1"});
ss.connect( targetAddress ); 

最佳答案

默认的 KeyManager 将发送它找到的第一个符合服务器请求条件的证书,也就是说,它将发送它找到的第一个可以为其建立证书链的证书服务器在请求期间发送的 CA 名称。

如果您总是希望选择一个特定的别名,您需要实现自己的 X509KeyManager ,可能包装默认管理器。这些方面的东西应该可以工作(没有测试这个实际代码,可能有一些拼写错误):

KeyStore keystore = ... // create and load your keystore.

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keystore, password.toCharArray());

final X509KeyManager origKm = (X509KeyManager)kmf.getKeyManagers()[0];

X509KeyManager km = new X509KeyManager() {
    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
        return "foo";
    }

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

    // Delegate the rest of the methods from origKm too...
}

然后将它用于您的 SSLContext:

SSLContext sslContext = sslContext.getInstance("TLS");
sslContext.init(new KeyManager[] { km }, null, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

关于java - 在连接之前,我如何告诉 SSLSocket 所需的 key 输入的别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15201251/

相关文章:

java - 当用户点击 osmdroid map 中的标记时如何设置标记 fragment ?

java - 通过另一个 JButton 启用/禁用一个 JButton

iis - 在 IIS 7.5 中要求设置 SSL 时忽略/禁止客户端/服务器 SSL 证书

asp.net - 即使数据不敏感,我是否需要在用户登录后保持 HTTPS (SSL) 状态?

java - 尝试使用 Java Keystore : Failed PKCS12 integrity checking 解析 WS2016 生成的 PKCS12

java - Spring Neo4j 事务回滚不起作用

spring - 嵌入式tomcat Spring boot中的ssl设置

java - 仅当 jar 已签名时才允许运行

java - 如何更改 Java Keystore(JKS) keystore 和别名密码以便它们正常工作

java - 反向迭代器 - 用于 reduceRight 功能