在改造库中禁用SSL证书检查

问题描述:

我在android中使用retrofit与服务器连接。在改造库中禁用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

如果您的开发服务器上没有ssl证书,为什么要使用https连接它? – njzk2

+0

@ njzk2:这是一个自签名证书。 URL aoti-重定向到“https”。 –

+0

为什么不将它添加到您的可信证书中?至少直到你做开发工作。 –

我强烈反对这样做

简短的回答 - 子类的HostnameVerifier,过程验证()总是返回true。

这有更好的选择

朗的答案 - 检查我(变得有点老)博客在这里:Making Android and SSL Work Together

也许您的方案

降HTTPS来最好的选择HTTP对于你的测试服务器,那么逻辑就不必改变。

HTH

实施代码,这样的解决方法,即使用于测试目的是不好的做法。

您可以:

  1. 生成您的CA.
  2. 使用CA为您的证书签名。
  3. 将您的CA添加为可信。

有些链接可能是有用的:

IMO,你可以阅读Google's documentation - Security with HTTPS and SSL

关于使用自我签署证书改造的示例代码,请尝试以下操作,希望它有帮助!

... 
@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(); 
} 
... 

使用此类获取不安全的改造实例。我已包括进口以避免混淆。

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); 
     } 
    } 
} 

,然后只需用改装没有SSL检查是这样

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(); 

      } 
     }); 
    } 

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。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; 
    } 
}