Java - поток Ssl отменяется при использовании аутентификации сертификата клиента - PullRequest
0 голосов
/ 18 мая 2018

Я не могу понять это.

У меня есть модульный тест, который выполняет подключение к моей службе с использованием аутентификации сертификата клиента.

// generate a valid client cert and store it in a keystore
String keystorePassword = "xxx";
InputStream pkcs12 = UnitTests.generatePkcs12ForUser(user, keystorePassword, 3600);
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(pkcs12, keystorePassword.toCharArray());


String url = getBaseServerUrl();

// prepare a ssl context that has the keystore with client cert and key
SSLContext sslContext = SSLContexts.custom()
                                   .loadKeyMaterial(ks, keystorePassword.toCharArray())
                                   // trust all SSL certs
                                   .loadTrustMaterial((X509Certificate[] chain, String authType) -> true)
                                   .build();

// validate any hostname, and don't follow 3XX responses
HttpClient httpClient = HttpClients.custom()
                                   .setSSLContext(sslContext)
                                   .setSSLHostnameVerifier((a,b) -> true)
                                   .disableRedirectHandling()
                                   .build();

// this fails catastrophically
HttpResponse response = httpClient.execute(new HttpGet(url));

Я использую Java 8 имой сервер находится за обратным прокси-сервером, использующим Nginx.

Мой модульный тест не проходит с исключением, подобным следующему:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
[...]
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:505)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
    ... 43 more

И я вижу в файле об ошибках Nginx следующую строку:

2018/05/18 15:34:12 [crit] 42#42: *327 SSL_do_handshake() failed (SSL: error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error) while SSL handshaking, client: 172.18.0.1, server: 0.0.0.0:443

Я НАУЧИЛ Интернет, чтобы найти причину этой ошибки, и я чувствую, что исчерпал все возможности.

Неисчерпывающий список вещей, которые я пробовал:

  • Заставить java использовать TlsV1.1 с -Dhttps.protocols=Tlsv1.1 -> по-прежнему не удается
  • Попытка указать "ключевую стратегию" для loadTrustMaterial, чтобы всегда использовать мой собственный ключ -> по-прежнему не удается
  • Использовал клиент Jersey с тем же набором параметров Ssl / Keystore -> все еще не работает
  • Пробовал все версии JDK 1.8: OpenJDK, Oracle и Oracle с Crypto Extensions (JCE)
  • При поиске ошибки nginx подразумевается, чтосертификат был неверным, поэтому я ...
  • ... выгрузил ключ и сертификат в пару файлов PEM, находясь в отладчике, и curl изменил тот же адрес -> он работает?!
  • Wiresharked соединение и проверил согласование TLS.По сравнению с рабочим примером (простой curl -k <url> выше, который работает безупречно):
    • Видел что-то о ALPN , но включение его в Java не устраняет исключение.
    • Видел разные криптоалгоритмы, но ничего не выделяется

У вас, ребята, есть идеи?Я начинаю сходить с ума.У меня есть предчувствие, что я неправильно устанавливаю соединение, но не вижу где.

1 Ответ

0 голосов
/ 20 июля 2019

Для тех, кто не читал комментарии: я понял: я использовал subjectAltName в качестве хранилища для чего-то, что не является альтернативным именем.

Кажется, что Java не устраиваетэто и отказывает в соединении.

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