Using this network library:
https://github.com/koush/ion
As the current status is development, I would like to use self-signed SSL cert
The library forum has some discussion:
https://github.com/koush/ion/issues/3
Ion ion = Ion.getDefault(c);
ion.configure().createSSLContext("TLS");
ion.getHttpClient().getSSLSocketMiddleware().setSSLContext(sslContext);
ion.getHttpClient().getSSLSocketMiddleware().setTrustManagers(trustManagers);
After some studies , I have grab the crt and getting sslContext and trustmanager, the problem is , it still return exception
javax.net.ssl.SSLException
Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Here is my attempt :
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.load);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
//System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
ssl_context = SSLContext.getInstance("TLS");
ssl_context.init(null, tmf.getTrustManagers(), null);
} catch (Exception e) {
Log.d("test1", "A: " + e);
}
Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware().setTrustManagers(tmf.getTrustManagers());
Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware().setSSLContext(ssl_context);
//test SSL
Ion.getDefault(this).with(this)
.load("https://na2b.no-ip.com/dragonair/can_app/api/media_list.php")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
if (e != null) {
Log.d("test1", "B: " + e);
} else {
Log.d("test1", "result" + result);
}
}
});
notice that the exception is at the B: part so that means trustmanager and SSLcontext should build correctly, how to fix that?
Thanks for helping.
Go to Settings / Security / Credential storage and select “Install from device storage”. The . crt file will be detected and you will be prompted to enter a certificate name. After importing the certificate, you will find it in Settings / Security / Credential storage / Trusted credentials / User.
Once you know a host's certificate or public key, you pin it to that host. In other words, you configure the app to reject all but one or a few predefined certificates or public keys. Whenever the app connects to a server, it compares the server certificate with the pinned certificate(s) or public key(s).
For your issue, IMO, you can refer to my following sample code. I have tested with my web service (Asp.Net WebAPI). Hope it helps!
public class MainActivity extends AppCompatActivity {
private Context mContext = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// cert file stored in \app\src\main\res\raw
InputStream caInput = getResources().openRawResource(R.raw.your_cert);
Certificate ca = cf.generateCertificate(caInput);
caInput.close();
KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, wrappedTrustManagers, null);
AsyncSSLSocketMiddleware sslMiddleWare = Ion.getDefault(mContext).getHttpClient().getSSLSocketMiddleware();
sslMiddleWare.setTrustManagers(wrappedTrustManagers);
sslMiddleWare.setHostnameVerifier(getHostnameVerifier());
sslMiddleWare.setSSLContext(sslContext);
// Post application/x-www-form-urlencoded and read a String
Ion.with(mContext)
.load("https://yourserver/token")
.setBodyParameter("grant_type", "password")
.setBodyParameter("username", "bnk")
.setBodyParameter("password", "bnk123456789")
.asString()
.setCallback(new FutureCallback<String>() {
@Override
public void onCompleted(Exception e, String result) {
if (result != null) {
Log.i("ionSample", result);
} else if (e != null) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private HostnameVerifier getHostnameVerifier() {
return new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
// or the following:
// HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
// return hv.verify("www.yourserver.com", session);
}
};
}
private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
return new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return originalTrustManager.getAcceptedIssuers();
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
try {
if (certs != null && certs.length > 0){
certs[0].checkValidity();
} else {
originalTrustManager.checkClientTrusted(certs, authType);
}
} catch (CertificateException e) {
Log.w("checkClientTrusted", e.toString());
}
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
try {
if (certs != null && certs.length > 0){
certs[0].checkValidity();
} else {
originalTrustManager.checkServerTrusted(certs, authType);
}
} catch (CertificateException e) {
Log.w("checkServerTrusted", e.toString());
}
}
}
};
}
}
Logcat output:
I/ionSample: {"access_token":"oS1SHxck8TzidTL...P-_6VFjRlDsjF9_A0JONu59rzYOVQV...ka78pHSvRPB5YrrBlHsF562Ay__Jd0MDfpOB0SRML2N8O3XPZK8woV4vjASzfGEzi7KJMmY8pkM_-P9ohHhWPD3PtgRahiqTUSapdpg6n197uJxdQWyU","token_type":"bearer","expires_in":2591999,"userName":"bnk",".issued":"Wed, 06 Jan 2016 06:26:45 GMT",".expires":"Fri, 05 Feb 2016 06:26:45 GMT"}
As the current status is development, I would like to ignore the SSL checking , but instead of replace https with http
Use Delete, Backspace, or equivalent operations to remove the s
from the https
scheme in your URL. Done.
This assumes that your server supports plain HTTP. If it does not, talk to whoever is maintaining the server.
Any experience in bypass the SSL checking (with using self sign cert) before?
Self-signed SSL certificates are not used to "bypass the SSL checking". If you are connecting to an HTTPS server that is using a self-signed certificate, then you configure Ion (or other HTTP clients) to recognize that certificate.
You "bypass the SSL checking" by not requesting an https://
URL, and having a server that supports a plain http://
URL.
And the problem is how to construct the sslContext obj / trust managers ?
If you actually have a server that is using a self-signed SSL certificate, you can use my CWAC-Security library to create the TrustManager[]
. Or, follow the Java snippets in Nikolay Elenkov's old blog post, adapting them for use with Ion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With