【发布时间】: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();来获取会话密码套件。
标签: java sockets networking ssl network-programming