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

Posted

技术标签:

【中文标题】如何指定要在 SSL 会话中使用的密码套件【英文标题】:How to specify the ciphersuite to be used in SSL session 【发布时间】:2012-12-06 06:31:38 【问题描述】:

我在端口 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() );

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

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

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

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

【问题讨论】:

它是一套加密选项,例如对称加密算法。 我知道 a 密码套件是什么。我问你密码套件是什么。真正谈判的那个。我还问你为什么认为你需要这样做。 它用于玩具 Java 应用程序中的测试和说明目的。我描述的问题一般不包括一个密码套件。例如:当我尝试连接到 hotmail.com 时,会话密码套件是:TLS_RSA_WITH_AES_128_CBC_SHA。当我尝试将它从我的 Java 应用程序更改为其他任何东西时,说:TLS_ECDHE_RSA_WITH_RC4_128_SHA,并再次尝试连接,为 theis SSL 会话选择的密码套件是:TLS_RSA_WITH_AES_128_CBC_SHA。据我了解 setEnableCiphersuite() 将使用我设置的密码套件。这对我不起作用(在几个例子中)。 在您明确调用startHandshake() 之前,您的代码中还有其他内容吗?您是否有电话给getSession() 或者您是否正在尝试使用 I/O 流进行读/写? (其中任何一个都会启动握手,可能在您拨打 setEnabledCipherSuites(...) 之前)。 我编辑了我的帖子并在握手之前添加了几行。握手之前没有getsession()。只有在它打印 sesison ciphersuite 之后。握手后,我拨打:socket.getInetAddress(); 获取IP。然后,我调用:socket.getSession().getCipherSuite(); 来获取会话密码套件。 【参考方案1】:

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

SSLSocket JavaDoc 中所述:

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

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

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

【讨论】:

以上是关于如何指定要在 SSL 会话中使用的密码套件的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 javax.net.ssl.SSLHandshakeException:没有共同的密码套件? [复制]

映射 SSL/TLS 密码套件及其 OpenSSL 等效项

如何在 Spring Boot 嵌入式 tomcat 中设置 HTTPS SSL 密码套件首选项

为 SSL 套接字启用哪些密码套件?

SSL Medium Strength Cipher Suites Supported (SWEET32) 支持SSL中等强度密码套件(SWEET32)中危漏洞

如何在 WebSphere 7.0.0.45 中使用强密码套件配置 TLS 1.2 协议?