如何在连接之前将所需密钥条目的别名告诉 SSLSocket? [英] How I can tell alias of the wanted key-entry to SSLSocket before connecting?

查看:17
本文介绍了如何在连接之前将所需密钥条目的别名告诉 SSLSocket?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 java 密钥库中有两个证书/密钥对.这些关键条目的别名是foo"和bar".

I have two certificate/key pairs in a java keystore. Aliases of those key-entries are "foo" and "bar".

我的 TLS 客户端(java 程序)使用密钥库.TLS 客户端身份验证在连接打开期间完成.当 TLS 服务器从客户端请求证书时,客户端程序应该使用foo"密钥输入.现在客户端在连接握手期间向服务器发送错误的证书(bar").

My TLS client (java program) uses the keystore. TLS client authentication is done during connection opening. The client program should use "foo" key-entry when TLS server request certificate from the client. Now the client send wrong certificate ("bar") to the server during connection handshake.

如何在连接前将所需密钥条目的别名告知 SSLSocket?

How I can tell alias of the wanted key-entry to SSLSocket before connecting?

目前代码如下:

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

推荐答案

默认的 KeyManager 将发送它找到的第一个与服务器请求的条件匹配的证书,即发送它找到的第一个可以为服务器在请求期间发送的 CA 名称之一构建认证链.

The default KeyManager will send the first certificate it finds that matches the conditions requested by the server, that is, it will send the first one it find for which it can build a certification chain up one of the CA names sent by the server during the request.

如果你总是想选择一个特定的别名,你需要实现你自己的X509KeyManager,可能包含默认管理器.沿着这些路线的东西应该可以工作(未测试此实际代码,可能有一些拼写错误):

If you always want a specific alias to be chosen, you'll need to implement your own X509KeyManager, possibly wrapping the default manager. Something along these lines should work (not tested this actual code, there may be a few typos):

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();

这篇关于如何在连接之前将所需密钥条目的别名告诉 SSLSocket?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆