我听到另一个朋友说:
所以我写了一些代码来测试它-看起来对于同一服务器和客户机的1000个连接-它总是选择相同的密码。为什么?
import javax.net.ssl.*; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.io.OutputStream; import java.net.SocketException; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; public class SSLServerClient { private static Set<String> cipherNames = new HashSet(); public static void main(String[] args) throws IOException { System.setProperty("javax.net.ssl.keyStore", "/path/KeyStore.jks"); System.setProperty("javax.net.ssl.trustStore", "/path/KeyStore.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "password"); for (int i = 0; i < 1000; i++) { SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket serverListeningSSLSocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(4380); SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket clientSocket = (SSLSocket) sslSocketFactory.createSocket(serverListeningSSLSocket.getInetAddress(), serverListeningSSLSocket.getLocalPort()); SSLSocket serverCommsSSLSocket = (SSLSocket) serverListeningSSLSocket.accept(); final byte[] bytes = "--Hello World!".getBytes(); final OutputStream out = clientSocket.getOutputStream(); final DataInputStream in = new DataInputStream(serverCommsSSLSocket.getInputStream()); (new Thread() { public void run() { int len = 0; try { len = in.read(); final byte[] b = new byte[len]; in.readFully(b); //System.out.println(new String(b)); } catch (SSLException | EOFException | SocketException | NegativeArraySizeException e) { // skip this one } catch (IOException e) { e.printStackTrace(); } } }).start(); out.write(bytes.length); out.write(bytes); //System.out.println("protocol: "+ clientSocket.getSession().getProtocol()); //System.out.println("cipher: " + clientSocket.getSession().getCipherSuite()); cipherNames.add(clientSocket.getSession().getCipherSuite()); clientSocket.close(); serverCommsSSLSocket.close(); serverListeningSSLSocket.close(); } System.out.println("Ciphers used: " + cipherNames); } }
结果是:
Ciphers used: [TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
同样的密码1000次。
握手选择最好的可用密码,这取决于一些完全确定的算法。对于相同的输入(即双方宣布的相同密码和版本,以及其他考虑因素),它将选择相同的密码。
假设选择是客观上最好的一个,就没有必要随机选择另一个(即次)密码。事实上那是个坏主意。
在您的客户机中禁用TLS_ECDHE_rsau WITH_AES_128_CBC_SHA256(或提供更好的功能),您将获得其他功能。