Почему соединение Java SSL все еще использует один и тот же шифр для одинаковых сокетов клиента и сервера? - PullRequest
0 голосов
/ 22 ноября 2018

Я слышал, как один друг сказал:

Для каждого SSL-соединения в Java - когда вы смотрите на отладку SSL - вы можете увидеть список шифров, доступных во время процесса рукопожатия, и этотвыбран.

Я слышал, как другой друг сказал:

Для одного и того же сокета SSL клиента и сервера в Java - они всегда будут выбирать один и тот же шифр.

Это мне казалось несоответствующим.Как вы могли бы рукопожатие со списком шифров и при этом каждый раз придумывать один и тот же шифр?

Поэтому я написал некоторый код для его проверки - и казалось, что для 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 раз.

Мой вопрос: Почему в SSL-соединении Java все еще используется один и тот же шифр для одинаковых сокетов клиента и сервера?

1 Ответ

0 голосов
/ 22 ноября 2018

Рукопожатие выбирает лучший из доступных шифров, в зависимости от алгоритма, который является полностью детерминированным.Для одного и того же ввода (т. Е. Одни и те же шифры и версии, объявленные доступными обеим сторонам и независимо от того, что еще учитывается) будет выбран один и тот же шифр.

При условии, что выбор является объективно лучшим, существуетнет смысла случайным образом выбирать другой (то есть подчиненный) шифр.На самом деле это было бы плохой идеей.

Отключите TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 в своем клиенте (или предоставьте что-нибудь получше), и вы получите что-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...