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

Java 如何指定SSL会话中要使用的密码套件,java,sockets,networking,ssl,network-programming,Java,Sockets,Networking,Ssl,Network Programming,我在端口443上创建了一个套接字,如下所示: socket = (SSLSocket) factory.createSocket(hostName, port); 然后,我想查看此套接字中启用的密码套件,我使用: String[] enCiphersuite=socket.getEnabledCipherSuites(); System.out.println("Enabled ciphersuites are: "+Arrays.toString(enCiphersuite)); 然后,我

我在端口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));
然后我进行了握手,并检查了会话密码套件:

socket.startHandshake();
System.out.println("Session ciphersuite is"+socket.getSession().getCipherSuite() );
但我发现,握手后在上一个printout语句中打印的密码的名称(据我所知,这是会话中实际使用的密码)不是我之前使用
setEnabledCipherSuite()设置的名称

为什么我仍然看不到我选择的密码套件是用过的?此外,我还尝试了
getEnablediPhone套件()
并在我
setEnablediPhone套件
之后打印出来,发现列表没有更改为我设置的内容。我不确定打印启用的密码套件时,此密码套件列表是否取决于Java且始终是同一列表,还是取决于客户端或服务器?有人能解释吗

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

SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory(); 
SSLSocket socket=null;
try {
socket = (SSLSocket) factory.createSocket(hostName, port);
socket.setSoTimeout(15000); 
socket.startHandshake(); //handshake
.
.
我发现我在 setEnableCipherSuite()以打印出启用的密码 在设置它们之前。当我移除它时,密码已经设置好了。为什么? 是吗

如以下文件所述:

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

  • 调用明确开始握手的startHandshake,或
  • 在该套接字上读取或写入应用程序数据的任何尝试都会导致隐式握手,或
  • 如果当前没有有效的会话,则对getSession的调用将尝试设置会话,并且隐式握手已完成

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

这是一套加密选项,例如对称加密算法。我知道密码套件是什么。我问你密码套件是什么。实际上是谈判的那个。我还问您为什么认为需要这样做,这是为了在玩具java应用程序中进行测试和演示。我描述的问题是一般性的,不包括一个密码套件。例如:当我尝试连接到hotmail.com时,会话密码套件是:
TLS\u RSA\u WITH\u AES\u 128\u CBC\u SHA
。当我尝试将其从Java应用程序更改为其他应用程序时,请说:
TLS\u ECDHE\u RSA\u WITH_RC4\u 128\u SHA
,然后再次尝试连接,为其SSL会话选择的密码套件是:
TLS\u RSA\u WITH_AES\u 128\u CBC\u SHA
。据我所知,setEnableCiphersuite()将使用我设置的ciphersuite。这不适用于我(在几个示例中)。在显式调用
startHandshake()
之前,代码中还有其他内容吗?您是否调用了
getSession()
,或者正在尝试使用I/O流进行读/写操作?(其中任何一个都会启动握手,可能是在您调用
setEnablediPhone套件(…)
)之前)。我编辑了我的帖子,并在握手前添加了几行。握手前没有
getsession()
。只有在它之后才能打印Seisson密码套件。握手之后,我调用:
socket.getInetAddress()以获取IP。然后,我调用:
socket.getSession().getCipherSuite()
以获取会话密码套件。