我在端口 443 上创建了一个套接字,如下所示:
socket = (SSLSocket) factory.createSocket(hostName, port);
然后,我想查看此套接字中启用的密码套件,我使用了:
String[] enCiphersuite=socket.getEnabledCipherSuites();
System.out.println("Enabled ciphersuites are: "+Arrays.toString(enCiphersuite));
然后,我只想选择一个密码套件供我的应用程序在与远程服务器创建握手时使用。我做了以下事情:
String pickedCipher[] ={"TLS_RSA_WITH_AES_128_CBC_SHA"};
socket.setEnabledCipherSuites(pickedCipher);
System.out.println("ciphersuite set to: "+Arrays.toString(pickedCipher));
然后我进行了握手,并检查了 session 密码套件:
socket.startHandshake();
System.out.println("Session ciphersuite is"+socket.getSession().getCipherSuite() );
但是我发现握手后在前面的打印输出语句中打印的密码名称(据我了解,这是 session 中实际使用的密码)不是我之前使用setEnabledCipherSuites()<设置的密码
为什么我仍然看不到我选择的密码套件是用过的?而且,我还尝试了 getEnabledCipherSuites()
并在我 setEnabledCipherSuites
之后打印出来,发现列表没有更改为我设置的内容。我不确定何时打印已启用的密码套件,此密码套件列表是否取决于 Java 并且始终是相同的列表,还是取决于客户端或服务器?任何人都可以解释吗?
编辑: 在握手之前,我只有以下几行:
SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory();
SSLSocket socket=null;
try {
socket = (SSLSocket) factory.createSocket(hostName, port);
socket.setSoTimeout(15000);
socket.startHandshake(); //handshake
.
.
最佳答案
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 中所述:
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.
如果您在调用setEnabledCipherSuite()
之前调用了getSession()
,那么当您尝试设置启用的密码套件时握手已经完成,因此本次 session 的密码套件已被选中。
关于java - 如何指定要在 SSL session 中使用的密码套件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13943351/