Reputation: 2703
My Android application should be able to communicate to any SSL enabled servers. As my app is demo application and my customers add their own SSL server details in the app while logging in, so upfront I don't know which SSL certificate I need to validate.
Following is my earlier code.
public SSLSocketFactory getSSLSocketFactory(String hostname) {
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[] { new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} }, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
return HttpsURLConnection.getDefaultSSLSocketFactory();
}
When I updated my to playstore, it was rejected with below reason
To properly handle SSL certificate validation, change your code in the checkServerTrusted method of your custom X509TrustManager interface to raise either CertificateException or IllegalArgumentException whenever the certificate presented by the server does not meet your expectations. For technical questions, you can post to Stack Overflow and use the tags “android-security” and “TrustManager."
I would like to update my code similar to this
public static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", ssf, 443));
return new DefaultHttpClient(ccm, base.getParams());
} catch (Exception ex) {
return null;
}
}
Does playstore accept this? is there any better way to handle this?
Thanks in Advance.
Upvotes: 8
Views: 41899
Reputation: 123
In case someone is looking to disable SSL certificate checking in a NativeScript Android app, here's how to convert Elad's answer's code to JavaScript:
const disableSSLCertificateCheckin = function () {
const trustAllCerts = [new javax.net.ssl.X509TrustManager({
getAcceptedIssuers: function () {
return null
},
checkClientTrusted: function (arg0, arg1) {
// Not implemented
},
checkServerTrusted: function (arg0, arg1) {
// Not implemented
},
})]
try {
const sc = javax.net.ssl.SSLContext.getInstance('TLS')
sc.init(null, trustAllCerts, new java.security.SecureRandom())
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier({
verify: function (hostname, session) {
return true
}
})
)
} catch (e) {
console.log('e :>> ', e);
}
}
disableSSLCertificateCheckin()
Thanks @Elad!
Upvotes: 2
Reputation: 51
This is an old post, but I hope it can help someone else. Problem is fixed with netcipher version 2.1.0 (SSLHandshakeException with v1.2.1)
File app/build.gradle
...
dependencies {
implementation 'info.guardianproject.netcipher:netcipher:2.1.0'
...
}
Upvotes: 1
Reputation: 1655
quoting the solution from: https://gist.github.com/aembleton/889392
The following code disables SSL certificate checking for any new instances of HttpsUrlConnection:
/**
* Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
* aid testing on a local box, not for use on production.
*/
public static void disableSSLCertificateChecking() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// Not implemented
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// Not implemented
}
} };
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } });
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
Upvotes: 10