12

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

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

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 ?

EDIT: 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
.
.
user1810868
  • 1,565
  • 8
  • 23
  • 30
  • It is the suite of crypto options such as symmetric encryption algorithm. – user1810868 Dec 19 '12 at 15:33
  • I know what *a* cipher suite is. I asked you what *the* cipher suite is. The one that was actually negotiated. I also asked why you think you need to do this. – user207421 Dec 20 '12 at 10:14
  • It is for testing & illustration purposes in a toy java application. The problem I described is general not inclusive for one ciphersuite. Ex: When I try to connect to hotmail.com, the session ciphersuite is: `TLS_RSA_WITH_AES_128_CBC_SHA`. when I try to change it from my Java application to anything else, say: `TLS_ECDHE_RSA_WITH_RC4_128_SHA`, and try to connect, again, the chosen ciphersuite for theis SSL session is: `TLS_RSA_WITH_AES_128_CBC_SHA`. As far as I understand that setEnableCiphersuite() is going to use the ciphersuite I set. This is not working with me (in several examples). – user1810868 Dec 21 '12 at 18:36
  • Is there anything else in your code, before you call `startHandshake()` explicitly? Do you have a call to `getSession()` or are you trying to read/write using the I/O streams? (Either of these would initiate the handshake, possibly before you make the call to `setEnabledCipherSuites(...)`). – Bruno Dec 22 '12 at 15:30
  • I edited my post and added the few lines before the handshake. There is no `getsession()` before the handshake. Only after it to print the sesison ciphersuite. After the handshake, I call: `socket.getInetAddress();` to get the IP. Then, I call: `socket.getSession().getCipherSuite();` to get the session cipher suite. – user1810868 Dec 22 '12 at 20:49
  • Keep in mind that not all SSL servers support all cipher combinations. –  Dec 22 '12 at 20:56
  • "duskwuff: that is true. some ciphers result in a message `connection reset`. But even those who are supported, the application does not gives any error but does not set the cipher. – user1810868 Dec 22 '12 at 21:23
  • @Bruno: 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 ? – user1810868 Dec 22 '12 at 21:30

1 Answers1

6

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 ?

As documented in the SSLSocket JavaDoc:

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

  • calling startHandshake which explicitly begins handshakes, or
  • any attempt to read or write application data on this socket causes an implicit handshake, or
  • a call to getSession tries to set up a session if there is no currently valid session, and an implicit handshake is done.

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.

Bruno
  • 119,590
  • 31
  • 270
  • 376