2017-12-01 9 views
0

서버와의 SSL 연결을 추가하려고 시도했지만 불행히도 작동하지 않습니다. 여전히 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.입니다.SSL 클라이언트 인증서 okhttp3을 연결하십시오. 핸드 셰이크가 실패했습니다.

작업의 순서 :

  • 요청에서 응용 프로그램 측에서 서버

  • 전송 만든 인증서를 인증서를 생성 우리가 예를 사용하는 인증서를 가지고 MIIEpzCCAo+gAwIBAgICALQwDQYJKoZIhvcNAQELBQAwgYAxCzAJBgNVBAYTAlBM[...]6AlW6gjevIU7ZP2lIZWmA9f5uPc3Js1aft3UHmVfdiTaG+rcAVsw+ck7aQ== (ROOT_CA)

  • 다음 요청은 첨부 된이 인증서 (ROOT_CA)와 함께 전송됩니다.

인증서를 전송하는 코드 책임은 :

private void retrofitConfiguration(Context context){ 
      OkHttpClient.Builder client = new OkHttpClient.Builder(); 
      ProviderInstaller.installIfNeeded(context); 
      X509Certificate ca = loadCertificate(); 
      KeyStore keyStore = createKeyStore(ca); 
      TrustManager[] trustManagers = createTrustManager(keyStore); 
      SSLContext sslContext = null; 
      sslContext = createSSLContext(trustManagers, keyStore); 
      X509TrustManager _trustManager = (X509TrustManager) trustManagers[0]; 
      client.sslSocketFactory(sslContext.getSocketFactory(), _trustManager); 
      client.hostnameVerifier(getHostnameVerifier()); 
      buildRetrofit(client.build()); 
    } 

    private X509Certificate loadCertificate() throws CertificateException { 
     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     String ca = ROOT_CA; 
     byte[] decoded = Base64.decode(ca); 
     return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(decoded)); 
    } 

    private KeyStore createKeyStore(X509Certificate ca) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { 
     String keyStoreType = KeyStore.getDefaultType(); 
     KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
     keyStore.load(null, null); 
     keyStore.setCertificateEntry("ca", ca); 
     return keyStore; 
    } 

    private TrustManager[] createTrustManager(KeyStore keyStore) throws NoSuchAlgorithmException, KeyStoreException { 
     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(keyStore); 
     return tmf.getTrustManagers(); 
    } 

    private SSLContext createSSLContext(TrustManager[] trustManagers, KeyStore keyStore) throws KeyManagementException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException { 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 

     KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); 
     kmf.init(keyStore, new char[]{0}); 
     KeyManager[] keyManagers = kmf.getKeyManagers(); 

     sslContext.init(keyManagers, trustManagers, null); 
     return sslContext; 
    } 


    private HostnameVerifier getHostnameVerifier() { 
     return (hostname, session) -> { 
      return true; 
     }; 
    } 

나는 같은 결과 https://github.com/rfreedman/android-ssl에서 CustomTrustManager을 사용했습니다.

는 정말 그 시점에서 작동하지 않는 이유를하지 않습니다 .. 어떤 도움을 크게 감상 할 수

(이 같은 다른 주제의 많은 일을했다)!

UPDATE 지금 나는이 방법을 사용하고 있습니다 :

private SSLSocketFactory getSSLSocketFactory() 
     throws CertificateException, KeyStoreException, IOException, 
     NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException { 

    Certificate clientCA = parseClientCertificate(); 
    KeyStore clientKeyStore = KeyStore.getInstance("BKS"); 
    clientKeyStore.load(null, null); 
    clientKeyStore.setCertificateEntry("clientCA", clientCA); 
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509"); 
    keyManagerFactory.init(clientKeyStore, null); 
    KeyManager[] keyManagers = keyManagerFactory.getKeyManagers(); 


    Certificate rootCA = parseRootCertificate(); 
    KeyStore rootKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    rootKeyStore.load(null, null); 
    rootKeyStore.setCertificateEntry("rootCA", rootCA); 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmf.init(rootKeyStore); 
    TrustManager[] managers = tmf.getTrustManagers(); 

    SSLContext sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(keyManagers, managers, null); 
    return sslContext.getSocketFactory(); 
} 

을 그리고 javax.net.ssl.SSLHandshakeException: Handshake failed를 받고. 이 연결은 https이고 클라이언트 인증서를 요청에 첨부하려고합니다. (okhttp3 및 android 7.1.1로 테스트). 나는 스택에서 많은 주제를 훑어 보았고 어떤 해결책도 찾을 수 없었다.

전체 스택 추적 :

W: javax.net.ssl.SSLHandshakeException: Handshake failed 
W:  at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:[email protected]:54) 
W:  at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:267) 
W:  at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:237) 
W:  at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:148) 
W:  at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:186) 
W:  at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121) 
W:  at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100) 
W:  at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at com.network.ApiClient.lambda$retrofitConfiguration$0(ApiClient.java:127) 
W:  at com.network.ApiClient$$Lambda$1.intercept(Unknown Source) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179) 
W:  at okhttp3.RealCall.execute(RealCall.java:63) 
W:  at retrofit2.OkHttpCall.execute(OkHttpCall.java:174) 
W:  at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:40) 
W:  at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:24) 
W:  at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:33) 
W:  at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:25) 
W:  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) 
W:  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) 
W:  at rx.Observable.unsafeSubscribe(Observable.java:10346) 
W:  at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100) 
W:  at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230) 
W:  at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
W:  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428) 
W:  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
W:  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) 
W:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
W:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
W:  at java.lang.Thread.run(Thread.java:761) 
W: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7f8f068740: Failure in SSL library, usually a protocol error 
W: error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (third_party/openssl/boringssl/src/ssl/tls_record.cc:575 0x7f8f0fb180:0x00000001) 
W:  at com.google.android.gms.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
W:  at com.google.android.gms.org.conscrypt.SslWrapper.doHandshake(:[email protected]:2) 
W:  at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:[email protected]:19) 
W: ... 43 more 
W: com.network.errors.RetrofitException: Handshake failed 
W:  at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper.asRetrofitException(RxErrorHandlingCallAdapterFactory.java:93) 
W:  at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper.access$000(RxErrorHandlingCallAdapterFactory.java:51) 
W:  at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper$1.call(RxErrorHandlingCallAdapterFactory.java:71) 
W:  at com.network.RxErrorHandlingCallAdapterFactory$RxCallAdapterWrapper$1.call(RxErrorHandlingCallAdapterFactory.java:68) 
W:  at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140) 
W:  at retrofit2.adapter.rxjava.BodyOnSubscribe$BodySubscriber.onError(BodyOnSubscribe.java:64) 
W:  at retrofit2.adapter.rxjava.CallArbiter.emitError(CallArbiter.java:141) 
W:  at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:43) 
W:  at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:24) 
W:  at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:33) 
W:  at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:25) 
W:  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) 
W:  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) 
W:  at rx.Observable.unsafeSubscribe(Observable.java:10346) 
W:  at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100) 
W:  at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230) 
W:  at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
W:  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428) 
W:  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
W:  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) 
W:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
W:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
W:  at java.lang.Thread.run(Thread.java:761) 
W: Caused by: javax.net.ssl.SSLHandshakeException: Handshake failed 
W:  at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:[email protected]:54) 
W:  at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:267) 
W:  at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:237) 
W:  at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:148) 
W:  at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:186) 
W:  at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121) 
W:  at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100) 
W:  at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at com.network.ApiClient.lambda$retrofitConfiguration$0(ApiClient.java:127) 
W:  at com.network.ApiClient$$Lambda$1.intercept(Unknown Source) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
W:  at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
W:  at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179) 
W:  at okhttp3.RealCall.execute(RealCall.java:63) 
W:  at retrofit2.OkHttpCall.execute(OkHttpCall.java:174) 
W:  at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:40) 
W: ... 15 more 
W: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7f8f068740: Failure in SSL library, usually a protocol error 
W: error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (third_party/openssl/boringssl/src/ssl/tls_record.cc:575 0x7f8f0fb180:0x00000001) 
W:  at com.google.android.gms.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
W:  at com.google.android.gms.org.conscrypt.SslWrapper.doHandshake(:[email protected]:2) 
+0

자사가 https://stackoverflow.com/questions/9249158/why-do-i-get-a-handshake-failure-java- 같이 :

는 내 키 스토어에 이것을 추가했다 SSL을 사용하지만 해결책이 없습니다. 클라이언트 인증서가 로컬에서 생성되고 서버에 보내고 서명 한 후 응답으로 반환합니다. 그러나 키 저장소가이를 무시하고 서버에 보내지 않는 것처럼 보입니다. – Ikazuchi

+0

getCertificateChain ("clientCA") 반환 값 null – Ikazuchi

답변

0

내가 그것을 얻었다!

Certificate[] chain = new Certificate[] {clientCA, rootCA}; 
    keyStore.setCertificateEntry("clientCA", clientCA); 
    keyStore.setCertificateEntry("rootCA", rootCA); 
    keyStore.setKeyEntry("keys", getPrivateKey(), password, chain);