2

Я пытаюсь вызвать вызов POST Rest с помощью Spring RestTemplate:Ошибка: Получен фатальным предупреждение: handshake_failure

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); 

RestTemplate restTemplate = new RestTemplate(requestFactory); 

HttpHeaders headers = new HttpHeaders(); 

headers.setContentType(MediaType.APPLICATION_XML); 

HttpEntity<GetBalanceHistoryRequest> request1 = new  HttpEntity<GetBalanceHistoryRequest>(request, headers); 
String result = restTemplate.postForObject("https://server.com/getBalance", request1, String.class); 

https://server.com имеют сертификат: webapi.tartu-x86.p12 импортировать сертификат в C: \ Java_8 \ JRE \ Lib \ безопасность \ cacerts usinf Keytool

после запуска моего кода я получаю следующее сообщение об ошибке:

SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder] 
trustStore is: C:\Java_8\jre\lib\security\cacerts 
trustStore type is : jks 
trustStore provider is : 
init truststore 
adding as trusted cert: 
    Subject: CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US 
    Issuer: CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US 
    Algorithm: RSA; Serial number: 0xc3517 
    Valid from Mon Jun 21 07:00:00 IDT 1999 until Mon Jun 22 07:00:00 IDT 2020 

adding as trusted cert: 
    Subject: CN=SecureTrust CA, O=SecureTrust Corporation, C=US 
    Issuer: CN=SecureTrust CA, O=SecureTrust Corporation, C=US 
.... 
.... 

** Finished 
verify_data: { 31, 64, 180, 145, 192, 1, 180, 119, 86, 70, 247, 140 } 
*** 
[write] MD5 and SHA1 hashes: len = 16 
0000: 14 00 00 0C 1F 40 B4 91 C0 01 B4 77 56 46 F7 8C [email protected] 
Padded plaintext before ENCRYPTION: len = 48 
0000: 14 00 00 0C 1F 40 B4 91 C0 01 B4 77 56 46 F7 8C [email protected] 
0010: 3F 56 B1 14 65 F3 18 C6 B3 98 D3 50 65 AC 74 1A ?V..e......Pe.t. 
0020: 48 11 50 C0 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B H.P............. 
main, WRITE: TLSv1 Handshake, length = 48 
[Raw write]: length = 53 
0000: 16 03 01 00 30 B6 A0 43 3D 91 3A C1 F6 34 F5 73 ....0..C=.:..4.s 
0010: 54 A7 1A 46 84 42 1A DC 0D 4D B9 4A C1 3F CB A6 T..F.B...M.J.?.. 
0020: 57 C6 5D DF C4 1D 62 22 92 FB 1F 3E F1 05 0C 5C W.]...b"...>...\ 
0030: 56 9E 9B 02 2D          V...- 
[Raw read]: length = 5 
0000: 15 03 01 00 02          ..... 
[Raw read]: length = 2 
0000: 02 28            .(
main, READ: TLSv1 Alert, length = 2 
main, RECV TLSv1 ALERT: fatal, handshake_failure 
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA] 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: Received     fatal alert: handshake_failure 
main, called close() 
main, called closeInternal(true) 

Я использую Java 1.8.0_91

любой может здесь помочь?

ответ

1

Причина явы SSL проблема, как handshake_failure, как правило, это:

  • Несовместимые шифры: Клиент должен использовать шифры с поддержкой сервером
  • Несовместимые версий SSL/TLS: Клиент должны убедиться, что он использует совместимую версию. Например, сервер может заставить TLS1.2, который по умолчанию не включен в java7 (не ваш случай)
  • Неполный путь доверия для сертификата сервера: серверный сертификат, вероятно, не доверен клиенту. Обычно исправление заключается в том, чтобы импортировать цепочку сертификатов сервера в хранилище доверия клиентов.
  • Плохая конфигурация сервера, например, сертификат, выданный другому домену или цепочке сертификатов, неполный. В случае, если исправление находится на серверной части

В вашем случае кажется, что был выбран TLSv1, когда java8 использует TLSv1.2 по умолчанию, поэтому возможно, что сервер не обновлен последними версиями.

Я предлагаю отлаживать протокольные сообщения ClientHello и ServerHello для просмотра выбранного протокола и шифрования из пакета.

-Djavax.net.debug=ssl 

Также вы можете проверить состояние вашего сервера в SSLLabs

+0

Спасибо за ваш повторе, как я могу сказать java, чтобы использовать TLSv1? – Yosefarr

+0

java8 будет использовать TLSv1.2 по умолчанию, но если он недоступен, он будет использовать TLSv1.1 или TLSv1. Если соединение выбирает TLSv1, это связано с тем, что сервер не поддерживает TLSv1.2 или вообще не шифрует – pedrofb

0

У меня была такая же проблема, и я решил так:

1 - Преобразование файл p12 в файл KeyStore Java (.jks расширение) и поместить в папку ресурсов вашего проекта:

keytool -importkeystore -srckeystore <pfxfilename.pfx> -srcstoretype pkcs12 -destkeystore <jks-filename.jks> -deststoretype JKS 

2 - Реализовать завод запрос на использование вами JKS файл:

RestTemplate restTemplate = new RestTemplate(); 

ClientHttpRequestFactory requestFactory = null; 
try { 
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    keyStore.load(
      this.getClass().getClassLoader().getResourceAsStream("jks-filename.jks"), //put your .jks file name here. 
      "password".toCharArray()); //the .jks file password. 

    SSLConnectionSocketFactory socketFactory = 
      new SSLConnectionSocketFactory(
        new SSLContextBuilder() 
        .loadTrustMaterial(null, new TrustSelfSignedStrategy()) 
        .loadKeyMaterial(keyStore, "password".toCharArray()).build()); //the .jks file password again... 

    HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build(); 
    requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); 

} catch (Exception e) { 
    e.printStackTrace(); 
} 

restTemplate.setRequestFactory(requestFactory); 

3 - Возможно, вам потребуется добавить Apache Httpclient в свой проект. В проекте «Грейдл» добавить:

compile ("org.apache.httpcomponents:httpclient") 

Готов!

Другой быстрое решение просто создать файл JKS и поместить файл и пароль в качестве параметра JVM:

-Djavax.net.ssl.keyStore=/absolute/file/location/java/application/keystore.jks 
-Djavax.net.ssl.keyStorePassword=jkspassword 

или положить в Java класс статический блок:

System.setProperty("javax.net.ssl.keyStore", "/absolute/file/location/java/application/keystore.jks"); 
System.setProperty("javax.net.ssl.keyStorePassword", "jkspassword"); 
Смежные вопросы