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

查看:134
本文介绍了如何在连接之前告诉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天全站免登陆