代码之家  ›  专栏  ›  技术社区  ›  hawkeye

为什么Java SSL连接对同一个客户机和服务器套接字仍然使用相同的密码?

  •  0
  • hawkeye  · 技术社区  · 6 年前

    我听到另一个朋友说:

    所以我写了一些代码来测试它-看起来对于同一服务器和客户机的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次。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Thilo    6 年前

    握手选择最好的可用密码,这取决于一些完全确定的算法。对于相同的输入(即双方宣布的相同密码和版本,以及其他考虑因素),它将选择相同的密码。

    假设选择是客观上最好的一个,就没有必要随机选择另一个(即次)密码。事实上那是个坏主意。

    在您的客户机中禁用TLS_ECDHE_rsau WITH_AES_128_CBC_SHA256(或提供更好的功能),您将获得其他功能。