我听一位 friend 说:
For every SSL Connection in Java - when you look at the SSL debug - you can see the list of ciphers available during the handshake process, and that one is chosen.
我听另一个 friend 说:
For the same client and server SSL Sockets in Java - they will always choose the same cipher.
这对我来说似乎是不一致的。你怎么能用一系列密码握手并且每次仍然想出相同的密码?
所以我写了一些代码来测试它 - 似乎对于同一服务器和客户端的 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 次。
我的问题是:为什么 Java SSL 连接仍然对相同的客户端和服务器套接字使用相同的密码?
最佳答案
握手选择最佳可用密码,这取决于完全确定的算法。对于相同的输入(即双方声明可用的相同密码和版本以及考虑的任何其他因素),它将选择相同的密码。
假设选择是客观上最好的,随机选择另一个(即劣质)密码是没有意义的。事实上,这不是一个好主意。
在您的客户端中禁用 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(或提供更好的东西),您会得到其他东西。
关于java - 为什么 Java SSL 连接仍然对相同的客户端和服务器套接字使用相同的密码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53430336/