2017-05-13 8 views
0

정말이 문제를 해결하는 방법을 모르겠다.이 프로젝트는 Docker 컨테이너 서버에 RoR 백엔드 API가있는 Android 및 iOs 앱이다 ...android Retrofit and OkHttpClient Error SSL 핸드 셰이크 백엔드에서 인증서를 암호화하자.

안드로이드 앱에서 api 클라이언트 구현을 위해 Retrofit Library를 사용했고 모든 것이 완벽하게 작동했습니다 ... SSL 인증서가 서버에 구현 될 때까지는. 내 파트너는 우편 배달부, 내가 곱슬 곱슬와 API를 성공적으로 요청을 할 수 있습니다, 그것을위한 Let’s Encrypt를 사용 ...하지만 내 안드로이드 응용 프로그램은 항상 말 : 때때로

D/Error: SSL handshake aborted: ssl=0xXXXXXXXX: I/O error during system call, Connection reset by peer 

나 :

D/Error: SSL handshake timeout 

ApiClient 소스 : ...

,369

public class ApiClient { 

public static final String DOMAIN = "qwerty.xyz"; //not the real url obviously 
public static final String BASE_URL = "https://api." + DOMAIN; 

private static Retrofit retrofit = null; 

private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); 

private static Gson gson = new GsonBuilder() 
     .create(); 

private static Retrofit.Builder builder = 
     new Retrofit.Builder() 
       .baseUrl(BASE_URL) 
       .addConverterFactory(GsonConverterFactory.create(gson)); 

public static <S> S createService(Class<S> serviceClass) { 
    return createService(serviceClass, null, null); 
} 

public static <S> S createService(Class<S> serviceClass, String username, String password) { 
    Retrofit retrofit = builder.client(getUnsafeOkHttpClient()) 
      .build(); 
    return retrofit.create(serviceClass); 
} 

public static OkHttpClient getUnsafeOkHttpClient() { 

    try { 
     // Create a trust manager that does not validate certificate chains 
     final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { 
      @Override 
      public void checkClientTrusted(
        java.security.cert.X509Certificate[] chain, 
        String authType) throws CertificateException { 
      } 

      @Override 
      public void checkServerTrusted(
        java.security.cert.X509Certificate[] chain, 
        String authType) throws CertificateException { 
      } 

      @Override 
      public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
       return new java.security.cert.X509Certificate[0]; 
      } 
     } }; 

     // Install the all-trusting trust manager 
     final SSLContext sslContext = SSLContext.getInstance("SSL"); 
     sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); 
     // Create an ssl socket factory with our all-trusting manager 
     final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); 


     OkHttpClient okHttpClient = httpClient.sslSocketFactory(sslSocketFactory).hostnameVerifier(new HostnameVerifier() { 

        @Override 
        public boolean verify(String hostname, SSLSession session) { 
                  return true; 
                } 
               }) 
             .build(); 

     return okHttpClient; 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 

} 

관찰은의 SSLSocketFactory 방법은되지 않습니다 ...하지만 그것을 할 수있는 새로운 방법이 얼마나 모르겠어요

저는 'com.squareup.retrofit2 : retrofit : 2.2.0'을 사용하고 있습니다 ...

정말로 해결책을 찾아 주셔서 감사합니다.

UPDATE 서명

하자 암호화 사용 TLSv1.2 프로토콜이 아닌 자기 & 솔루션, 우리는 TSL의의 이전 버전을 제외해야합니다.

public class TLSSocketFactory extends SSLSocketFactory { 

    private SSLSocketFactory internalSSLSocketFactory; 

    public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { 
     SSLContext context = SSLContext.getInstance("TLS"); 
     context.init(null, null, null); 
     internalSSLSocketFactory = context.getSocketFactory(); 
    } 

    @Override 
    public String[] getDefaultCipherSuites() { 
     return internalSSLSocketFactory.getDefaultCipherSuites(); 
    } 

    @Override 
    public String[] getSupportedCipherSuites() { 
     return internalSSLSocketFactory.getSupportedCipherSuites(); 
    } 

    @Override 
    public Socket createSocket() throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket()); 
    } 

    @Override 
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); 
    } 

    @Override 
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); 
    } 

    @Override 
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); 
    } 

    @Override 
    public Socket createSocket(InetAddress host, int port) throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); 
    } 

    @Override 
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); 
    } 

    private Socket enableTLSOnSocket(Socket socket) { 
     if(socket != null && (socket instanceof SSLSocket)) { 
      ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"}); 
     } 
     return socket; 
    } 
} 

을 한 후 우리와 트러스트 매니저와 HttpClient를이 :

나는 정의의 SSLSocketFactory이 작업을 수행하기 위해 만드는

final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { 
       @Override 
       public void checkClientTrusted(
         java.security.cert.X509Certificate[] chain, 
         String authType) throws CertificateException { 
       } 

       @Override 
       public void checkServerTrusted(
         java.security.cert.X509Certificate[] chain, 
         String authType) throws CertificateException { 
       } 

       @Override 
       public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
        return new java.security.cert.X509Certificate[0]; 
       } 
      } }; 
      client = httpClient.sslSocketFactory(new TLSSocketFactory(), (X509TrustManager)trustAllCerts[0]) 
        .build(); 
      Retrofit retrofit = builder.client(client) 
        .build(); 

봐라!

+0

SSL 용 .crt 파일이 있습니까? 또한 .crt 파일을 로컬로 포함하고 OkHttp 클라이언트에 추가 할 수 있습니다. –

+0

인증은 정적이 아니며 항상 상쾌합니다. – lromano

+0

서버에서 사용 가능한 암호를 확인해야합니다. 또한 인증서 유효성 검사를 우회하려고하는 이유가 있습니까? –

답변

0

한 번 살펴보기 certificate pinning

+0

Retrofit2에 대한 적절한 해결책이 아닐 수도 있습니다. –