Android应用SSL证书

时间:2016-02-10 08:05:26

标签: android ssl retrofit

我有一个需要连接到具有SSL证书的服务器的Android应用程序。

我对此很陌生。你能告诉我相信证书的步骤吗?

我正在为我的Rest Client使用Retrofit库

2 个答案:

答案 0 :(得分:1)

如果要使用自签名证书,请使用以下代码(它将创建一个不验证证书链的信任管理器):

public class RestModule {
private RestAdapter mRestAdapter;
private RaasService mRaasService;
private String mAccessToken;

public RestModule(final Context context, final String endPoint)
{
    init(context, endPoint);
}
public RestModule(final Context context, final String endPoint, final String accessToken) {
    mAccessToken = accessToken;
    init(context, endPoint);
}
public void init(final Context context, final String endPoint) {
    final MyPreferences preference = MyPreferences.getInstance();
    final RestAdapter.Builder builder = new RestAdapter.Builder().setLogLevel(RestAdapter.LogLevel.FULL)
            .setRequestInterceptor(new RequestInterceptor() {
                @Override
                public void intercept(RequestFacade requestFacade) {
                    if (mAccessToken == null) {
                        mAccessToken = preference.getCurrentAccountAccessToken();
                    }
                    requestFacade.addHeader("secretToken", mAccessToken);
                    requestFacade.addHeader("Content-Type", "application/json;charset=UTF-8");
                }
            })
            .setEndpoint(endPoint);
    builder.setClient(new OkClient(getUnsafeOkHttpClient()));
    mRestAdapter = builder.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 null;
                    }
                }
        };

        // 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 = new OkHttpClient();
        okHttpClient.setSslSocketFactory(sslSocketFactory);
        okHttpClient.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
        okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
        okHttpClient.setReadTimeout(30, TimeUnit.SECONDS);
        return okHttpClient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public RaasService getService() {
    if (mRaasService == null) {
        mRaasService = mRestAdapter.create(RaasService.class);
    }
    return mRaasService;
}

}

要使用您的SSL证书,请使用以下方法代替getUnsafeOkHttpClient:

    public static OkHttpClient trustcert(Context context){
    OkHttpClient okHttpClient = new OkHttpClient();
    try {
        KeyStore ksTrust = KeyStore.getInstance("BKS");
        InputStream instream = context.getResources().openRawResource(R.raw.mykeystore);
        ksTrust.load(instream, "secret".toCharArray());
        // TrustManager decides which certificate authorities to use.
        TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ksTrust);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
    } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException e) {
        e.printStackTrace();
    }
    return okHttpClient;
}

您可以在https://viksaaskool.wordpress.com/2015/01/12/ssl-android-and-retrofit-some-frustration-might-occur/

找到更多详情

答案 1 :(得分:1)

以下是具有适当信任存储的previously posted answer

public class RestModule {
     private RestAdapter mRestAdapter;
     private RaasService mRaasService;
     private String mAccessToken;

     public RestModule(final Context context, final String endPoint)
     {
          init(context, endPoint);
     }
     public RestModule(final Context context, final String endPoint, final String accessToken) {
          mAccessToken = accessToken;
          init(context, endPoint);
     }
     public void init(final Context context, final String endPoint) {
          final MyPreferences preference = MyPreferences.getInstance();
          final RestAdapter.Builder builder = new RestAdapter.Builder().setLogLevel(RestAdapter.LogLevel.FULL)
                  .setRequestInterceptor(new RequestInterceptor() {
                      @Override
                      public void intercept(RequestFacade requestFacade) {
                          if (mAccessToken == null) {
                              mAccessToken = preference.getCurrentAccountAccessToken();
                          }
                          requestFacade.addHeader("secretToken", mAccessToken);
                          requestFacade.addHeader("Content-Type", "application/json;charset=UTF-8");
                      }
                  })
                  .setEndpoint(endPoint);
          builder.setClient(new OkClient(getPinnedOkHttpClient(context)));
          mRestAdapter = builder.build();

     }

     private static OkHttpClient getPinnedOkHttpClient(Context context) {
          try {
              final SSLContext sslContext = getSslContext(context);
              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 = new OkHttpClient();
              okHttpClient.setSslSocketFactory(sslSocketFactory);
              okHttpClient.setHostnameVerifier(new HostnameVerifier() {
                  @Override
                  public boolean verify(String hostname, SSLSession session) {
                      return true;
                  }
              });
              okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
              okHttpClient.setReadTimeout(30, TimeUnit.SECONDS);
              return okHttpClient;
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
     }

     private SSLContext getSslContext(Context context) throws Exception {
         KeyStore trustStore = loadTrustStore(context);
         String algotithmName = TrustManagerFactory.getDefaultAlgorithm();
         TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(algotithmName);
         trustManagerFactory.init(trustStore);
         SSLContext sslContext = SSLContext.getInstance("TLS");
         sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
         return sslContext;
     }

     private KeyStore loadTrustStore(Context context) throws Exception {
         KeyStore trustStore = KeyStore.getInstance("BKS");
         InputStream trustStoreStream = context.getResources().getAssets().open("trust.bks");
         trustStore.load(trustStoreStream, "password".toCharArray());
         return trustStore;
     }

     public RaasService getService() {
          if (mRaasService == null) {
              mRaasService = mRestAdapter.create(RaasService.class);
          }
          return mRaasService;
     }
}

您必须将服务器证书放在BKS密钥库中,并使用trust.bks作为信任存储区的密码,放入assets文件夹中名为password的文件中。在情况下,在代码中使用(公开)已知密码是没有问题的,因为信任存储中没有存储单个保密字节,只保留公知的服务器证书。

This SO answer告诉您如何从服务器证书创建BKS密钥库。