I am trying to learn how to do certificate pinning in an Android application. I found the tutorial here. I wanted to clarify I doubt I have based on my testing this code.
I used the code as follows :
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;
}
}
Quoting a statement from that tutorial :
On the client side, you simply need to distribute the signing certificate
with your app and validate against it.
On my web server, I have my own CA, which I created using open SSL, and used to sign certificates for different domain names that are used with my app.
This statement indicates that this tutorial is meant for the CA certificate I have. I tested the code using ca.pem (from my CA's crt file) and it works fine.
But I also tested the same code with a certificate I signed with that CA, e.g. server.pem ( from the signed server.crt), and still it works.
Did I do something wrong, or is this code meant for pinning either :
1) a CA certificate (covering all certificates signed by that CA) or
2) a particular certificate (signed by some CA) ?
TrustManager
. Override thecheckServerTrusted
. For CA pinning, you're removing the CA Zoo and only using the one true CA. No other CA from the Zoo can claim to certify your site. For certificate pinning, your ensuring you get the expected server certificate. If you pin the server, you should choose the public key rather than the certificate. See OWASP's Certificate and Public Key Pinning. – Demonstrateneed to ensure your pinset is not tampered with
.. If I pin public key, I will generate pin and use in my app .. I think I don't follow – Monotony