
Android Java用の「プラグイン」で、SSL証明書についてユーザーに確認を求めることを可能にする
MemorizingTrustManager (MTM) は、Android で SSL をよりスマートかつ安全に利用できるようにするプロジェクトです。未知の SSL 証明書に遭遇した場合、証明書を一度だけ受け入れるか、恒久的に受け入れるか、接続を中止するかをユーザーに尋ねます。これは、無効、自己署名、および/または期限切れの証明書を盲目的に受け入れることによる中間者攻撃を防ぐための一歩です。
MTM はあなたの Android アプリケーションへのシームレスな統合を提供することを目的としており、ソースコードは MIT ライセンスの下で利用可能です。

MemorizingTrustManager は yaxim XMPP クライアント で本番運用されています。これは利用可能で統合も簡単ですが、まだホスト名検証には対応していません(Java API によって統合が困難になっています)。
MTM はあなた自身のアプリケーションに簡単に統合できます。以下の手順に従うか、example ディレクトリにあるデモアプリケーションを参照してください。
GitHub から MTM ソースをダウンロードするか、git サブモジュール として追加します:
# plain download:
git clone https://github.com/ge0rg/MemorizingTrustManager
# submodule:
git submodule add https://github.com/ge0rg/MemorizingTrustManager
その後、default.properties にライブラリプロジェクトの依存関係を追加します:
android.library.reference.1=MemorizingTrustManager
AndroidManifest.xml を編集し、閉じる </application> タグの直前に MTM アクティビティ要素を追加します。
...
<activity android:name="de.duenndns.ssl.MemorizingActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
/>
</application>
</manifest>
HTTPS 接続で MemorizingTrustmanager をフックする:
// register MemorizingTrustManager for HTTPS
SSLContext sc = SSLContext.getInstance("TLS");
MemorizingTrustManager mtm = new MemorizingTrustManager(this);
sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(
mtm.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()));
SSLSocket の場合は、次のようにします:
// register MemorizingTrustManager for all SSLSockets
SSLContext sc = SSLContext.getInstance("TLS");
MemorizingTrustManager mtm = new MemorizingTrustManager(this);
HostnameVerifier hv = mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier());
sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
SSLContext.setDefault(sc);
// connect a socket
SSLSocket s = ...;
s.startHandshake();
if (!hv.verify(your_domain_name, sslSocket.getSession())) {
throw new CertificateException("Server failed to authenticate as " + your_domain_name);
}
または、Smack の場合は setCustomSSLContext() を使用できます:
org.jivesoftware.smack.ConnectionConfiguration connectionConfiguration = …
SSLContext sc = SSLContext.getInstance("TLS");
MemorizingTrustManager mtm = new MemorizingTrustManager(this);
sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
connectionConfiguration.setCustomSSLContext(sc);
connectionConfiguration.setHostnameVerifier(
mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier()));
デフォルトでは、MTM はユーザーに尋ねる前にシステムの TrustManager にフォールバックします。この仕組みを信頼できない場合は、コンストラクタに defaultTrustManager = null パラメータを渡すことで、新しい接続ごとにダイアログを強制できます:
MemorizingTrustManager mtm = new MemorizingTrustManager(this, null);
AndroidPinning のような別の基盤となる TrustManager を使用したい場合は、それを MTM のコンストラクタに渡すだけです:
X509TrustManager pinning = new PinningTrustManager(SystemKeyStore.getInstance(),
new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"}, 0);
MemorizingTrustManager mtm = new MemorizingTrustManager(this, pinning);
MTM はロギングに java.util.logging (JUL) を使用します。JUL 用の Handler を設定していない場合、Android はデフォルトで Level.INFO 以上のすべてのメッセージをログに記録します。デバッグログメッセージ(Level.FINE 以下のもの)も取得するには、それに応じて Handler を設定する必要があります。MTM のサンプルプロジェクトには de.duenndns.mtmexample.JULHandler が含まれており、実行時にデバッグログの有効/無効を切り替えることができます。
MemorizingTrustManager は唯一の選択肢ではありません。
NetCipher は、Guardian Project がモバイルアプリのネットワークセキュリティを向上させるために作成した Android ライブラリです。より徹底した証明書チェックを行う StrongTrustManager、独立したルート CA ストア、そして Orbot を使用してトラフィックを Tor ネットワーク に簡単にルーティングするためのコードが含まれています。
AndroidPinning は、Moxie Marlinspike によって書かれたもう 1 つの Android ライブラリで、サーバー証明書のピン留めを可能にし、政府規模の MitM 攻撃に対するセキュリティを向上させます。あなたのアプリが特定のサーバーと通信するために作られている場合は、これを使用してください!
どうか MTM をより多くの言語に翻訳するのを手伝ってください!