2014-04-10 2 views
0

SSLv3 보안을 사용하여 서비스에 연결하려고합니다.Apache httpclient javax.net.ssl.SSLHandshakeException :

통신은 다음 파일

1. ca.crt 
2. private.key 
2. client.crt 
내가 cmd를

openssl pkcs12 -export -in client.crt -inkey private.key -CAfile ca.crt -out sslstore.p12 

를 다음과와의 SSL 키 스토어를 만들기 위해 모든 3 개 개의 파일을 사용

을 제공 한 후 컬 및 브라우저와 함께 작동하고 가져 오기에 키 도구를 사용 그것과 마찬가지로 자바 트러스트 스토어

keytool -importkeystore -srckeystore sslstore.p12 -srcstoretype PKCS12 -destkeystore truststore.jks 

나는 URL에 연결하려면 https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java 링크를 클릭하십시오. 프로토콜 만 TLSv1에서 SSLv3으로 변경합니다.

나는 항상 javax.net.ssl.SSLHandshakeException을 얻는다 : 연결하는 동안 예외.

이미 언급했듯이 키는 컬/브라우저에서 작동합니다.

sslcontext = SSLContexts.custom()       
        .loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()) 
        .build(); 

에 :

EDIT-2 에서 SSLContexts.custom 근처 코드()

변경

sslcontext = SSLContexts.custom() 
        .loadKeyMaterial(keyStore, "changeit".toCharArray()) 
        .loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()) 
        .build(); 

일했다. 동일한 키 저장소를 사용하고 있습니다.

EDIT-1 코드 :

public static void main (String[] args) throws KeyStoreException, FileNotFoundException { 


     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 

     InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("certs/ppro.jks"); 

     try { 
      keyStore.load(is,"changeit".toCharArray()); 
     } catch (IOException | NoSuchAlgorithmException | CertificateException e) { 
      e.printStackTrace(); 
     } 
     // Trust own CA and all self-signed certs 
     SSLContext sslcontext = null; 
     try { 
      sslcontext = SSLContexts.custom() 
        .loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()) 
        .build(); 
     } catch (NoSuchAlgorithmException | KeyManagementException e) { 
      e.printStackTrace(); 
     } 
     try { 
      sslcontext.loadKeyMaterial(keyStore,"changeit".toCharArray()); 
     } catch (NoSuchAlgorithmException | KeyManagementException e) { 
      e.printStackTrace(); 
     } 
     // Allow TLSv1 protocol only 
     SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
       sslcontext, 
       new String[] { "SSLv3" } , 
       null, 
       SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); 

     try (CloseableHttpClient httpclient = HttpClients.custom() 
       .setSSLSocketFactory(sslsf) 
       .build()) { 
      HttpPost httpPost = new HttpPost(URL); 
      try { 

       CloseableHttpResponse response = httpclient.execute(httpPost); 
       System.out.println(response); 

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

    } 

EDIT-0 여기

일부 SSL 디버그 정보를 포함하여 자바에서 스택 트레이스입니다. 다음 시도 -

*** ClientKeyExchange, RSA PreMasterSecret, SSLv3 
main, WRITE: SSLv3 Handshake, length = 132 
SESSION KEYGEN: 
PreMaster Secret: 
0000: 03 00 E7 89 C2 9D AB 1A 3B 75 85 5B 4E C6 EE 10 ........;u.[N... 
0010: 83 0F 3C 37 74 3C D0 6A AF 51 D7 EC E2 B9 50 35 ..<7t<.j.Q....P5 
0020: CC 8D 58 93 39 5D B6 4F BE DB 5A F4 E3 0A BE 42 ..X.9].O..Z....B 
CONNECTION KEYGEN: 
Client Nonce: 
0000: 53 47 9A BD 4B 14 BC AF B0 2B FB 6C 49 9C E4 53 SG..K....+.lI..S 
0010: 21 F3 53 C8 7F 74 1C 5C C0 5E 6D 67 18 50 10 4D !.S..t.\.^mg.P.M 
Server Nonce: 
0000: 53 47 9A BD B2 5C 44 89 92 BE 4B FF F4 F6 60 FE SG...\D...K...`. 
0010: D6 18 67 96 6A 13 3C 80 9F D2 56 29 1A 60 B4 E4 ..g.j.<...V).`.. 
Master Secret: 
0000: E3 E5 11 9F 87 B6 A3 4E 8C 9C F1 20 E9 A5 50 62 .......N... ..Pb 
0010: DD E8 E6 A3 61 FC C0 56 0C 1E A8 29 BC F4 5C 52 ....a..V...)..\R 
0020: DE CE 98 64 0E 57 07 E6 22 24 08 1A 77 8A 97 48 ...d.W.."$..w..H 
Client MAC write Secret: 
0000: 44 98 8B 9C C4 59 C2 4E 21 66 67 6D 96 C4 FE 9C D....Y.N!fgm.... 
0010: 2B 74 AD 61          +t.a 
Server MAC write Secret: 
0000: 29 7D 5A F2 71 B6 55 C0 CF BB 82 66 02 03 B1 35 ).Z.q.U....f...5 
0010: 5A 69 83 99          Zi.. 
Client write key: 
0000: B5 32 F7 7C DC DB 4F B4 00 48 66 A4 B3 C0 7D 6B .2....O..Hf....k 
Server write key: 
0000: CB 80 F4 76 53 92 6F 87 3B A3 9D B2 A9 6F 40 85 ...vS.o.;[email protected] 
Client write IV: 
0000: B7 89 4A FC 43 7A 1B 3C DD 83 7F CE A1 FC FB BF ..J.Cz.<........ 
Server write IV: 
0000: 84 92 B7 B4 EB 13 B6 77 EF 87 B0 E1 04 41 5C 4D .......w.....A\M 
main, WRITE: SSLv3 Change Cipher Spec, length = 1 
*** Finished 
verify_data: { 116, 66, 54, 146, 216, 200, 254, 221, 170, 236, 204, 2, 17, 139, 161, 37, 205, 117, 131, 95, 255, 123, 158, 100, 150, 110, 105, 209, 22, 205, 31, 196, 95, 84, 59, 252 } 
*** 
main, WRITE: SSLv3 Handshake, length = 64 
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) 
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) 
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:275) 
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:254) 
    at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:118) 
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314) 
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363) 
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219) 
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) 
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85) 
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) 
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) 
    at com.masterpayment.frontend.gateway.beconnector.GiroGateClient.main(GiroGateClient.java:66) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
main, READ: SSLv3 Alert, length = 2 
main, RECV SSLv3 ALERT: fatal, handshake_failure 
%% Invalidated: [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA] 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

답변

1

apache 예제는 트러스트 스토어 만 설정합니다. 그러면 CA 인증서 만 사용됩니다. 클라이언트 인증서를 처리하기위한 "ID"도 설정해야합니다. 나는 당신이 그들 모두를 같은 자바 키 스토어에 넣는다는 것을 깨닫는다. 그리고 그것은 일 것이다. 아마 (여전히 그들은 별개의 파일에있다)이다.

이 예제에서는 loadTrustMaterial()을 호출합니다. 또한 loadKeyMaterial()을 호출해야합니다.

+0

예제 나 링크를 제공 할 수 있습니까? 신원을 어떻게 만들 수 있습니까? – rangalo

+1

이미 신원을 만들었습니다. CA 인증서를 사용하여 동일한 키 저장소에 넣었습니다. SSLContexts.custom() 주위에 코드를 게시하십시오 –

+0

SSLContexts.custom() 주위의 코드를 sslcontext = SSLContexts.custom() 으로 변경했습니다. loadKeyMaterial (keyStore, "changeit".toCharArray()) .loadTrustMaterial (keyStore, new TrustSelfSignedStrategy()) .build(); – rangalo

0

내 직감은 당신이 PKIX 체인 verficiation 오류를 얻고 있다는 것입니다 : 위의

openssl pkcs12 \ 
    -export \ 
    -chain \ 
    -in client.crt \ 
    -inkey private.key \ 
    -CAfile ca.crt \ 
    -out sslstore.p12 

주 - 나는 '쇄'옵션을 추가 한 -이 제대로해야 적절한 인증서 체이닝을 사용하여 인증서를 PKCS # 12 아카이브로 내 보냅니다.

저는 지난 6 개월 동안 생각할 수있는 것보다 더 많은 시간을 보냈습니다.

그래도 해결되지 않으면 Java에서 스택 추적을 일부 추가하십시오.

+0

나는 그것을 시도했다. 이번에는 javax.net.ssl.SSLHandshakeException이 발생했습니다 : sun.security.validator.ValidatorException : PKIX path building failed : error. $ JRE_HOME/lib/security/cacerts에 이미 ca.crt를 가져 왔습니다. – rangalo

+0

이것은 트러스트 스토어에서 ca.crt를 가져 오기 전까지 발생합니다. 가져온 후에 원래 질문에서 언급 한 예외가 발생합니다. – rangalo

+0

나는 그 예외의 모호함을 싫어한다. 로컬로 이것을 증명하려고 노력하고 싶습니다. 어떤 버전을 사용하고 있는지 말해 줄 수 있습니까? –

관련 문제