2016-06-07 1 views
6

안드로이드에 추가 장착하여 서버에 연결하고 있습니다.개장 라이브러리에 SSL 인증서 확인 사용 안 함

public class ApiClient { 
    public static final String BASE_URL = "https://example.com/"; 
    private static Retrofit retrofit = null; 

    public static Retrofit getClient() { 
     if (retrofit==null) { 
      retrofit = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 
     } 
     return retrofit; 
    } 
} 

이것은 내 개발자입니다. 서버 및 인증서 확인을 사용하지 않으려합니다. 이 코드에서 어떻게 구현할 수 있습니까?

ERROR: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

+0

dev 서버에 ssl 인증서가없는 경우 https를 사용하여 연결하는 이유는 무엇입니까? – njzk2

+0

@ njzk2 : 자체 서명 된 인증서입니다. URL은'https'로 리디렉션됩니다. –

+0

신뢰할 수있는 인증서에 추가하지 않는 이유는 무엇입니까? 최소한 당신이 개발 작업을 할 때까지. –

답변

2

난 강력하게이

짧은 대답을하고 낙담 - 서브 클래스의 HostnameVerifier, 이상 승차 확인() 항상 true를 반환 할 수 있습니다.

이 더 나은 옵션있다

긴 대답 - 여기 내 (꽤 늙어) 블로그 확인 : Making Android and SSL Work Together

을 아마 시나리오

드롭에서 HTTPS에 대한 최선의 선택 HTTP 테스트 서버의 경우 로직을 변경할 필요가 없습니다. 심지어 테스트 목적으로 코드에서 이러한 해결 방법의

HTH

2

IMO, 당신은 Google's documentation - Security with HTTPS and SSL을 읽을 수 있습니다.

자체 서명 인증서로 Retrofit을 사용하는 샘플 코드는 다음을 참조하십시오. 도움이 되었으면합니다.

... 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    try{ 
     OkHttpClient client = new OkHttpClient.Builder() 
       .sslSocketFactory(getSSLSocketFactory()) 
       .hostnameVerifier(getHostnameVerifier()) 
       .build(); 

     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(API_URL_BASE) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .client(client) 
       .build(); 

     WebAPIService service = retrofit.create(WebAPIService.class); 

     Call<JsonObject> jsonObjectCall = service.getData(...); 
     ... 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

// for SSL...  
// Read more at https://developer.android.com/training/articles/security-ssl.html#CommonHostnameProbs 
private HostnameVerifier getHostnameVerifier() { 
    return new HostnameVerifier() { 
     @Override 
     public boolean verify(String hostname, SSLSession session) { 
      return true; // verify always returns true, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames 
      //HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); 
      //return hv.verify("localhost", session); 
     } 
    }; 
}   

private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) { 
    final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0]; 
    return new TrustManager[]{ 
      new X509TrustManager() { 
       public X509Certificate[] getAcceptedIssuers() { 
        return originalTrustManager.getAcceptedIssuers(); 
       } 

       public void checkClientTrusted(X509Certificate[] certs, String authType) { 
        try { 
         if (certs != null && certs.length > 0){ 
          certs[0].checkValidity(); 
         } else { 
          originalTrustManager.checkClientTrusted(certs, authType); 
         } 
        } catch (CertificateException e) { 
         Log.w("checkClientTrusted", e.toString()); 
        } 
       } 

       public void checkServerTrusted(X509Certificate[] certs, String authType) { 
        try { 
         if (certs != null && certs.length > 0){ 
          certs[0].checkValidity(); 
         } else { 
          originalTrustManager.checkServerTrusted(certs, authType); 
         } 
        } catch (CertificateException e) { 
         Log.w("checkServerTrusted", e.toString()); 
        } 
       } 
      } 
    }; 
} 

private SSLSocketFactory getSSLSocketFactory() 
     throws CertificateException, KeyStoreException, IOException, 
     NoSuchAlgorithmException, KeyManagementException { 
    CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
    InputStream caInput = getResources().openRawResource(R.raw.your_cert); // File path: app\src\main\res\raw\your_cert.cer 
    Certificate ca = cf.generateCertificate(caInput); 
    caInput.close(); 
    KeyStore keyStore = KeyStore.getInstance("BKS"); 
    keyStore.load(null, null); 
    keyStore.setCertificateEntry("ca", ca); 
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
    tmf.init(keyStore); 
    TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers()); 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(null, wrappedTrustManagers, null); 
    return sslContext.getSocketFactory(); 
} 
... 
14

안전하지 않은 Retrofit 인스턴스를 가져 오려면이 클래스를 사용하십시오. 혼란을 피하기 위해 수입품을 포함 시켰습니다.

import java.security.cert.CertificateException; 

import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.SSLSocketFactory; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 

import okhttp3.OkHttpClient; 
import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 
import view.utils.AppConstants; 

/** 
* Created by Hitesh.Sahu on 11/23/2016. 
*/ 

public class NetworkHandler { 

    public static Retrofit getRetrofit() { 

     return new Retrofit.Builder() 
       .baseUrl(AppConstants.BASE_URL) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .client(getUnsafeOkHttpClient()) 
       .build(); 
    } 


    private 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[]{}; 
         } 
        } 
      }; 

      // 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.Builder builder = new OkHttpClient.Builder(); 
      builder.sslSocketFactory(sslSocketFactory); 
      builder.hostnameVerifier(new HostnameVerifier() { 
       @Override 
       public boolean verify(String hostname, SSLSession session) { 
        return true; 
       } 
      }); 

      OkHttpClient okHttpClient = builder.build(); 
      return okHttpClient; 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

그리고 단순히이

private void postFeedbackOnServer() { 

     MyApiEndpointInterface apiService = 
       NetworkHandler.getRetrofit().create(MyApiEndpointInterface.class); 

     Call<ResponseBE> call = apiService.submitFeedbackToServer(requestObject); 

     Log.e(TAG , "Request is" + new Gson().toJson(requestObject).toString()); 

     call.enqueue(new Callback<ResponseBE>() { 
      @Override 
      public void onResponse(Call<ResponseBE> call, Response<ResponseBE> response) { 
       int statusCode = response.code(); 

       if (statusCode == HttpURLConnection.HTTP_OK) { 

       ...... 

       } else { 
        Toast.makeText(FeedbackActivity.this, "Failed to submit Data" + statusCode, Toast.LENGTH_SHORT).show(); 
       } 
      } 

      @Override 
      public void onFailure(Call<ResponseBE> call, Throwable t) { 

       // Log error here since request failed 
       Toast.makeText(FeedbackActivity.this, "Failure" + t.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); 

      } 
     }); 
    } 
0
private boolean bypassSSLVerification = true; 
private boolean privateCA = false; 



if(bypassSSLVerification) 
      { 
       IO.setDefaultSSLContext(SSLContextManager.getTrustAllSSLContext()); 
       IO.setDefaultHostnameVerifier(new HostnameVerifier() 
       { 
        @Override 
        public boolean verify(String s, SSLSession sslSession) 
        { 
         return true; 
        } 
       }); 
      } 
      else if(privateCA) 
      { 
       IO.setDefaultSSLContext(SSLContextManager.getSSLContext(context)); 
      } 

SSLContextManager처럼 SSL 검사없이 개조를 사용합니다.java

public class SSLContextManager 
{ 
    public static SSLContext getSSLContext(Context context) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, KeyManagementException, NoSuchProviderException 
    { 
     // Load CAs from an InputStream 
     CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); 
     InputStream cert = context.getResources().openRawResource(R.raw.my_cert); // Place your 'my_cert.crt' file in `res/raw` 
     Certificate ca; 
     try 
     { 
      ca = cf.generateCertificate(cert); 
     } 
     finally 
     { 
      cert.close(); 
     } 

     // Create a KeyStore containing our trusted CAs 
     String keyStoreType = KeyStore.getDefaultType(); 
     KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
     keyStore.load(null, null); 
     keyStore.setCertificateEntry("ca", ca); 

     // Create a TrustManager that trusts the CAs in our KeyStore 
     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(keyStore); 

     // Create an SSLContext that uses our TrustManager 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(null, tmf.getTrustManagers(), null); 

     return sslContext; 
    } 

    public static SSLContext getTrustAllSSLContext() throws NoSuchAlgorithmException, KeyManagementException 
    { 
     // 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) { 
        } 

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

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

     // Install the all-trusting trust manager 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); 

     return sslContext; 
    } 
}