Android アプリケーションで証明書のピン留めを行う方法を学習しようとしています。ここでチュートリアルを見つけました。このコードのテストに基づいているとは思えないことを明確にしたかったのです。
次のようにコードを使用しました:
public class CertificatePinning {
static SSLSocketFactory constructSSLSocketFactory(Context context) {
SSLSocketFactory sslSocketFactory = null;
try {
AssetManager assetManager = context.getAssets();
InputStream keyStoreInputStream = assetManager.open("myapp.store");
KeyStore trustStore = KeyStore.getInstance("BKS");
trustStore.load(keyStoreInputStream, "somepass".toCharArray());
sslSocketFactory = new SSLSocketFactory(trustStore);
sslSocketFactory.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
}
catch(Exception e){
Log.d("Exception", e.getLocalizedMessage());
}
return sslSocketFactory;
}
public static HttpClient getNewHttpClient(Context context) {
DefaultHttpClient httpClient = null;
try {
SSLSocketFactory sslSocketFactory = constructSSLSocketFactory(context);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sslSocketFactory, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
httpClient = new DefaultHttpClient(ccm, params);
} catch (Exception e) {
Log.d("Exception", e.getLocalizedMessage() );
return null;
}
return httpClient;
}
}
そのチュートリアルからのステートメントを引用する:
On the client side, you simply need to distribute the signing certificate
with your app and validate against it.
私の Web サーバーには、オープン SSL を使用して作成した独自の CA があり、アプリで使用されるさまざまなドメイン名の証明書に署名するために使用されています。
このステートメントは、このチュートリアルが私が持っている CA 証明書を対象としていることを示しています。(CA の crt ファイルから) ca.pem を使用してコードをテストしたところ、正常に動作しました。
しかし、そのCAで署名した証明書、たとえばserver.pem(署名されたserver.crtから)でも同じコードをテストしましたが、それでも機能します。
私は何か間違ったことをしましたか、またはこのコードは次のいずれかを固定するためのものですか:
1) CA 証明書 (その CA によって署名されたすべての証明書をカバーする) または
2) 特定の証明書 (一部の CA によって署名されたもの) ?