Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Loading a self-signed SSL certificate .crt file and packaging it into a SSLSocketFactory for use with a HttpsURLConnection.
// Usage example...
HttpsURLConnection connection = (HttpsURLConnection) new URL("https://someurl.com").openConnection();
connection.setSSLSocketFactory(buildSslSocketFactory());
private static SSLSocketFactory buildSslSocketFactory(Context context) {
// Add support for self-signed (local) SSL certificates
// Based on http://developer.android.com/training/articles/security-ssl.html#UnknownCa
try {
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream is = context.getResources().getAssets().openAsset("somefolder/somecertificate.crt");
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
// System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
return context.getSocketFactory();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@rakshith-sangamone

This comment has been minimized.

Copy link

@rakshith-sangamone rakshith-sangamone commented Aug 20, 2015

hi what is load-er.crt

@hajubal

This comment has been minimized.

Copy link

@hajubal hajubal commented Aug 10, 2017

Thank u. this code helpful for me.

@andrew9526

This comment has been minimized.

Copy link

@andrew9526 andrew9526 commented Sep 9, 2017

Hi, I have issue in load-der.crt, How can I get the .crt? Thank you

@jrbistuer

This comment has been minimized.

Copy link

@jrbistuer jrbistuer commented Oct 19, 2017

Hi, this code is great but is giving me a problem with the Google Maps API, can anyone, please, help me? Thank you!

@cz-librarian

This comment has been minimized.

Copy link

@cz-librarian cz-librarian commented Apr 16, 2018

This is the gold I was looking for
"InputStream is = context.getResources().getAssets().openAsset("somefolder/somecertificate.crt");"

@amjadislam10

This comment has been minimized.

Copy link

@amjadislam10 amjadislam10 commented Feb 14, 2019

@erickok is it save to place certificate in assets ? what if someone decompile code and get our certificate from code. he can use it for api calling. waiting for your valuable comment.

@jampot5000

This comment has been minimized.

Copy link

@jampot5000 jampot5000 commented Jul 27, 2019

@amjadislam10 I hope you have realised this by now, but for anyone else, here you are loading your public key, if your api is only secured by the ssl keys you are doing something wrong.

@Bhanuchander210

This comment has been minimized.

Copy link

@Bhanuchander210 Bhanuchander210 commented Aug 30, 2019

@erickok what if i have CA.crt, restClient.crt and restClient.key files.... I am totally confused... :(

@alkaaf

This comment has been minimized.

Copy link

@alkaaf alkaaf commented Apr 8, 2020

@erickok what if i have CA.crt, restClient.crt and restClient.key files.... I am totally confused... :(

CA.crt is used for signing only
restClient.crt is going to loaded by function above
restclient.key is going to used by your server that your android use

@user201610

This comment has been minimized.

Copy link

@user201610 user201610 commented Jun 27, 2020

In my android app, I can only see the context.getResources().getAssets().openNonAssetFd(filename) function, not openAsset(filename). This code is very helpful but I still don't know where to put the certificate into. Any directory on an android device? Thanks.

@user201610

This comment has been minimized.

Copy link

@user201610 user201610 commented Jun 27, 2020

It is solved:

put the file under "app/src/main/res/raw" with a name such as "mycertificate.crt".

        int identifier = context.getResources().getIdentifier("mycertificate","raw",context.getPackageName());
        InputStream is = context.getResources().openRawResource(identifier);
@Fuji1405116

This comment has been minimized.

Copy link

@Fuji1405116 Fuji1405116 commented Dec 30, 2020

you can also solve it by :

InputStream is = context.getResources().getAssets().open("certs_server.crt");

where you have your *.crt file in src/main/assets folder.
In the 37th line of the above code, the "context" variable should be renamed to "sslContext"/other as it already exists or needed to call a static method from activity. Everything is just working fine. To understand all the detail and related security issues just follow this official documentation from where the above code snippet has come :

https://developer.android.com/training/articles/security-ssl.html#CommonProblems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment