Есть ли рекомендуемый способ установить соединение SSLSocket с одноранговым узлом с тайм-аутом на процесс рукопожатия - PullRequest
1 голос
/ 10 февраля 2020

Я прочитал некоторые ответы, которые не решают мой вопрос полностью, например Установка таймаута для рукопожатия SSLSocket . Этот ответ требует, чтобы я поместил незашифрованный сокет под SSLSocket, что я бы предпочел не делать, если есть альтернатива. Соответствующая часть моего кода выглядит следующим образом (к вашему сведению, я не пишу пароли жестко, это просто для тестирования):

private static SSLSocket establishConnection(InetAddress ipv4, int port) {

    try {

        int ksn = Stub.getKeystoreNum();
        SecurityUtilities su = new SecurityUtilities("truststore" + ksn + ".jks", "keystore" + ksn + ".jks", "trustcert", "mykey");

        KeyStore keystore = su.loadKeyStore("password".toCharArray());
        KeyStore truststore = su.loadTrustStore("password".toCharArray());

        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER);
        keyManagerFactory.init(keystore, "password".toCharArray());

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KEY_MANAGER);
        trustManagerFactory.init(truststore);

        // specify TLS version e.g. TLSv1.3
        SSLContext serverContext = SSLContext.getInstance(TLS_VERSION);
        serverContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), SecureRandom.getInstance(RNG_ALGORITHM, RNG_PROVIDER));

        // THIS CODE IS MY ATTEMPT AT ESTABLISHING AN SSLSOCKET WITH A TIMEOUT
        SSLSocketFactory fact = serverContext.getSocketFactory();
        SSLSocket socket = (SSLSocket) fact.createSocket();
        socket.connect(new InetSocketAddress(ipv4.getHostAddress(), port), CON_TIMEOUT);
        return socket;

    } catch (IOException | GeneralSecurityException e) {
        System.out.println("tls node connection failed");
    }

    return null;
}     

Мой код успешно устанавливает соединение, и, проверив его с помощью tcpdump, я обнаружил, что он действительно кажется, зашифровать данные, передаваемые с ним. Однако, поскольку я прочитал, что невозможно создать SSLSocket без его немедленного подключения, например,

return (SSLSocket) fact.createSocket(ipv4.getHostAddress(), port);

, и поскольку метод подключения определен в Socket, а не в SSLSocket, я чувствую, что совершаю какую-то ошибку. Кроме того, я видел несколько примеров, в которых используется метод SSLSocket.startHandshake () . Это необходимо, поскольку я успешно установил соединения только с предыдущей строкой кода?

Спасибо за любую помощь

...