Androidアプリ開発時のSSL周りメモ

メモっす

はい。忘れてまた調べそうな気がしなくもないので。

Charles で Genymotion の HTTPS をプロキシる

使用する Android はネットワークに Proxy 設定可能なバージョンであること。(たぶん4系以降)

  1. Genymotion で Android イメージを起動する
  2. Wifi の設定をロングタップ
  3. 設定を変更(Modify Network)
  4. 拡張設定を表示(Show Advanced Options)
  5. プロキシー設定をマニュアル(Manual)に変更
  6. IP: 10.0.3.2(Genymotion内のホスト直通マジックナンバー), Port: 8888 に設定
  7. SSL Certificates • Charles Web Debugging Proxy にある http://www.charlesproxy.com/ssl.zip からcharlesの証明書を落とす。
  8. adb push charles-proxy-ssl-proxying-certificate.crt /mnt/sdcard/charles.crt とかで転送する
  9. 転送した証明書を開いてデバイスに登録する
  10. Charles の Proxy Settings から Enable SSL Proxying を有効にする
  11. 適当に Locations を追加する
  12. おしまい

Hostname was not verified

テスト環境のオレ②証明環境とかで Hostname 'example.com' was not verified なエラーがでるときは、とりあえず以下のような感じでチェックを無効化する。

public static RestAdapter getBuilder() {
    ApiRequestInterceptor requestInterceptor = new ApiRequestInterceptor();

    HttpClient httpClient = new DefaultHttpClient();

    // Ignore all hostname ssl verifications
    if (BuildConfig.BUILD_TYPE.equals("debug")) {
        SSLSocketFactory sf = (SSLSocketFactory) httpClient.getConnectionManager()
                .getSchemeRegistry().getScheme("https").getSocketFactory();
        sf.setHostnameVerifier(new AllowAllHostnameVerifier());
    }

    return new RestAdapter.Builder()
            .setRequestInterceptor(requestInterceptor)
            .setClient(new ApacheClient(httpClient))
            .setEndpoint(SERVICE_ENDPOINT)
            .build();
}

これは Retrofit と ApacheClient な例。まあ、こんな感じでよかろう。

以降追記

かも

追記 ignores all SSL errors

HttpClientを okHttp に置き換えた。同じようにSSL周りのエラーを無視する実装

Snip2Code - Get OkHttpClient which ignores all SSL errors. より。

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;
      }
    });
    return okHttpClient;
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}