如何指定要在 SSL 会话中使用的密码套件

我在端口 443 上创建了一个套接字,如下行所示:

I have created a socket on port 443 as in the following line:

socket = (SSLSocket) factory.createSocket(hostName, port);

然后,我想查看此套接字中启用的密码套件,我使用了:

Then, I wanted to see the enabled ciphersuites in this socket, I used:

String[] enCiphersuite=socket.getEnabledCipherSuites();
System.out.println("Enabled ciphersuites are: "+Arrays.toString(enCiphersuite));

然后,我只想选择一个密码套件,我希望我的应用程序在与远程服务器创建握手时使用它.我做了以下事情:

Then, I want to pick only one ciphersuite that I want my application to use when creating handshake with the remote server. I did the following:

String pickedCipher[] ={"TLS_RSA_WITH_AES_128_CBC_SHA"}; 
socket.setEnabledCipherSuites(pickedCipher);
System.out.println("ciphersuite set to: "+Arrays.toString(pickedCipher));

然后我进行了握手,并检查了会话密码套件:

Then I made the handshake, and checked the session ciphersuite:

socket.startHandshake();
System.out.println("Session ciphersuite is"+socket.getSession().getCipherSuite() );

但是我发现握手后之前打印输出语句中打印的密码名称(据我了解,这是会话中实际使用的密码)不是我之前使用 setEnabledCipherSuites()

But I found that the name of the cipher printed in the previous printout statement after the handshake (as I understand, this is the actually used cipher in the session) is not what I set earlier using setEnabledCipherSuites()

为什么我仍然看不到我选择的密码套件是使用过的?而且,我还尝试 getEnabledCipherSuites() 并在我 setEnabledCipherSuites 后将其打印出来,发现列表没有更改为我设置的内容.我不确定当我打印启用的密码套件时,这个密码套件列表是依赖于 Java 并且总是相同的列表,还是取决于客户端或服务器?任何机构都可以解释吗?

Why am I still not see my chosen ciphersuite is the used one ? and also, I also tried to getEnabledCipherSuites() and print it out after I setEnabledCipherSuites and found the list has not changed to what I have set. I am not sure when I print the enabled ciphersuite, is this list of ciphersuites depends on Java and always the same list, or depends on the client or on the server? Can any body explain ?

在握手之前我只有以下几行:

Before the handshake I only have the following lines:

SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory(); 
SSLSocket socket=null;
try {
socket = (SSLSocket) factory.createSocket(hostName, port);
socket.setSoTimeout(15000); 
socket.startHandshake(); //handshake
.
.

推荐答案

我发现我在setEnableCipherSuite() 以打印出启用的密码在设置它们之前.当我删除它时,密码已设置.为什么是吗?

I found out that I added socket.getsession() before the setEnableCipherSuite() in order to print out the enabled cipheres before setting them. When I removed it, the cipher has been set. why is that ?

SSLSocket JavaDoc 中所述:

As documented in the SSLSocket JavaDoc:

此连接上的初始握手可以通过以下方式之一启动三种方式:

The initial handshake on this connection can be initiated in one of three ways:

  • 调用显式开始握手的 startHandshake,或
  • 在此套接字上读取或写入应用程序数据的任何尝试都会导致隐式握手,或者
  • 如果当前没有有效会话,则调用 getSession 会尝试建立会话,并完成隐式握手.

如果您在调用 setEnabledCipherSuite() 之前调用 getSession(),则当您尝试设置启用的密码套件时,握手已经完成,因此该会话的密码套件已被选中.

If you call getSession() before calling setEnabledCipherSuite(), the handshake has already been done when you try to set the enabled cipher suites, so this session's cipher suite has already been selected.

相关文章