Skip to content

Instantly share code, notes, and snippets.

@luckenzo
Created November 29, 2018 11:53
Show Gist options
  • Save luckenzo/416d9da141b302bfcfcd7b0d3b95489f to your computer and use it in GitHub Desktop.
Save luckenzo/416d9da141b302bfcfcd7b0d3b95489f to your computer and use it in GitHub Desktop.
Sample code for TLS implementation on Android apps
public class PinManager implements X509TrustManager {
/* Get a default keystore instance or specify your keystore type e.g., BKS */
KeyStore ks = KeyStore.getInstance(KeyStore. getDefaultType());
private String keyAlgorithm;
private PublicKey storedPubKey;
private String serial;
String alias = "myCert";
public PinManager(InputStream file) throws KeyStoreException {
try {
ks.load(file, password);
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
}
/* Get certificate and associated public key */
X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
storedPubKey = cert.getPublicKey();
keyAlgorithm = storedPubKey.getAlgorithm();
serial = cert.getSerialNumber().toString();
}
/* Create TrustManager with specified keystore */
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init((KeyStore) myStore);
for(TrustManager tm : tmf.getTrustManagers()) {
((X509TrustManager) tm).checkServerTrusted(chain,authType);}
}
catch(Exception e) {
throw new CertificateException(e);
}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
return; // The client is not authenticated but you can implement your own checks if desired
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
if(null == x509Certificates) { // throw error if cert chain is empty
throw new IllegalArgumentException("Server X509Certificate array is null");
}
/* Get server certificate's public key */
PublicKey pubKey = x509Certificates[0].getPublicKey();
/* Check if keys match */
final boolean keyMatch = pubKey.equals(storedPubKey);
if(!(null != authType && authType.equalsIgnoreCase(keyAlgorithm))) { // throw error if public key algorithm is not same
throw new CertificateException("Server AuthType does not match");
}
if (x509Certificates[0].getSerialNumber().toString() == serial)
throw new CertificateException("Server serial number doesn't match");
if(!keyMatch) {
throw new CertificateException("Public key expected does not match");
}
}
}
/* One of the keystore should be commented... */
/* Development environment keystore */
int myStore = R.raw.devStore;
/* Production environment keystore */
int myStore = R.raw.proStore;
/* Initialize SSL context with customized TrustManager */
try {
InputStream in = getResources().openRawResource(myStore); // create an input stream with specified keystore
TrustManager trustManager[] = {new PinManager(in)};
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, trustManager, null);
/* Create connection using customized socket factory*/
URL url = new URL("https://www.bob.com/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
urlConnection.setHostnameVerifier(hostnameVerifier);
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment