I found out that android 4 doesn't play well with ssl , when trying to contact an api with https it causes a crash
javax.net.ssl.SSLException: SSL handshake aborted: ssl=0xb8dbad20: I/O error during system call, Connection reset by peer
Here's what i tried from other similar questions:
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
try {
Logger.e("under lolipop");
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[] { new MyTrustManager() }, new SecureRandom());
client.sslSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
Logger.e("HTTPS"+ e.getMessage() );
}
}
Which didn't effect the outcome
And
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
try {
client.sslSocketFactory(new TLSSocketFactory(), (X509TrustManager)trustAllCerts[0])
.build();
Logger.e("SETUP TRUST SSL");
return client.build();
} catch (KeyManagementException e) {
Logger.e("SETUP TRUST SSL Failed "+e.getMessage());
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
Logger.e("SETUP TRUST SSL Failed "+e.getMessage());
e.printStackTrace();
}
}
return client.build();
}
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
} };
This code gives a different error :
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Is there anyway to fix this , I must support android 4 and also use https ,
Any help will do !
I ran into a similar issue on Android 4.4 some time ago when our backend dropped support for TLS 1.0 and 1.1. I solved this by installing a new security provider with Google Play Services ProviderInstaller.
In your apps gradle.build file add
implementation "com.google.android.gms:play-services-auth:16.0.1"
In your startup Activity call ProviderInstaller.installIfNeeded() as early as possible. Here is an example method that tries to install the provider:
private static void installGooglePlayServicesProvider(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { //Devices with Android 5.1+ should support TLS 1.x out of the box
try {
ProviderInstaller.installIfNeeded(context);
} catch (GooglePlayServicesRepairableException e) {
Log.e("ProviderInstaller", "Google Play Services is out of date!", e);
GoogleApiAvailability.getInstance().showErrorNotification(context, e.getConnectionStatusCode());
} catch (GooglePlayServicesNotAvailableException e) {
Log.e("ProviderInstaller", "Google Play Services is unavailable!", e);
}
}
}
For more information on ProviderInstaller see Goolge developer page:
Patch the security provider with ProviderInstaller
When using TLS 1.2 you might have to force enable support on some devices.
Take a look at the following acticle and their Tls12SocketFactory implementation: Working with TLS 1.2 on Android 4.4 and Lower
Okhttp 3.13.x has dropped support for TLS1.2 and below and only support for Android API 21+. You will have to use Okhttp 3.12.x version branch for using it with Android 4.x devices.
More here
Related
Good day,
I'm trying to connect to AWS IoT with android using its SDK, no problem with Android 7 and above. But there's a compatibility problem with below versions. This is detailed in this Issue. I tried using Paho as client library but I haven't been able to figure out how to use those certificates with the Socket factory. Any idea how can I use those certificates with some MQTT Client library?
In the Java SDK was pretty easy to connect and no problem at all, I didn't have to use a keystore for that. Why Android needs to use a keystore to manage those certificates?. Should I install those certificates in the security settings as well?
I have tried using this wrapper. But is quite confuse how it uses those keystores. It throws and exception as it can't create it. Using that wrapper I have been able make some modifications and make it run. But it doesn't trigger anything neither onFail or onSuccess.
This is what I have done:
The class SocketFactory can be found here
void MqttSetup() {
CLIENT = new MqttAndroidClient(getBaseContext(), BROKER, MqttClient.generateClientId());
MQTT_CONNECTION_OPTIONS = new MqttConnectOptions();
/**
* SSL broker requires a certificate to authenticate their connection
* Certificate can be found in resources folder /res/raw/
*/
SocketFactory.SocketFactoryOptions socketFactoryOptions = new SocketFactory.SocketFactoryOptions();
try {
socketFactoryOptions.withCaInputStream(getResources().openRawResource(R.raw.keystore));
MQTT_CONNECTION_OPTIONS.setSocketFactory(new SocketFactory(socketFactoryOptions));
} catch (IOException | NoSuchAlgorithmException | KeyStoreException | CertificateException | KeyManagementException | UnrecoverableKeyException e) {
e.printStackTrace();
}
}
void MqttConnect() {
try {
final IMqttToken token = CLIENT.connect(MQTT_CONNECTION_OPTIONS);
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
// We are connected
Log.d("mqtt:", "connected, token:" + asyncActionToken.toString());
subscribe(TOPIC, (byte) 1);
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
// Something went wrong e.g. connection timeout or firewall problems
Log.d("mqtt:", "not connected" + asyncActionToken.toString());
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
When I try to connect to the broker it seems that it can make a connection as it's registered in the Monitor of Aws IoT. But those listeners don't get triggered and there are no thrown exceptions. I thought that I might not be loading those certificates properly.
I have the next files downloaded from Aws IoT (not sure how to bind them in a keystore and access them):
certificate.pem.crt
private.pem.key
public.pem.key
Thanks.
Attempting to establish an SSLSession using a self-signed certificate and the new-ish Network Security Configuration method as well as cwac-netsecurity library for backward compatibility works on all other versions of android (that I have tried) except Android 7.0.
I have an android app that connects to a device to provide a UI for that device. The connection uses a TLSv1 SSLSocket and a self-signed server certificate on the device side. Prior to Nougat, I had the server certs embedded as a BKS key store and loaded at run-time to create a custom TrustManager in order to intialize the SSL context and create the socket. This no longer works under Android 7+. Following some other questions on SO (Cannot connect via SSL using self signed certificate on Android 7 and above), I was able to use the Network Security Configuration method to establish the SSLSocket connection on an Android 8 device (https://developer.android.com/training/articles/security-config#ConfigCustom). For backward compatibility, I am using the cwac-netsecurity library from CommonsWare (https://github.com/commonsguy/cwac-netsecurity). I built a small test application and am testing against openssl s_server. What I have written establishes an SSLSession successfully from android devices running 4.4, 6.0, and 8.0. For some reason however, it does not do so on an android device running 7.0. Here are code snippets that show the test. Any help would be appreciated.
Test code in android app
{
// createSocketFactory
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault(); //null;
TrustManagerBuilder tmb = new TrustManagerBuilder();
tmb.withManifestConfig(MainActivity.this);
tmb.withCertChainListener(
new CertChainListener()
{
#Override
public void onChain(X509Certificate[] chain, String domain)
{
if (domain == null)
{
Log.d(TAG, "onChain: Certificate chain for request to unknown domain");
}
else
{
Log.d(TAG, "onChain: Certificate chain for request to: " + domain);
}
for (X509Certificate cert : chain)
{
Log.d(TAG, "onChain: Subject: " + cert.getSubjectX500Principal().getName());
Log.d(TAG, "onChain: Issuer: " + cert.getIssuerX500Principal().getName());
}
}
});
CompositeTrustManager ctm = tmb.build();
try
{
SSLContext sc = SSLContext.getInstance("TLSv1");
sc.init(null, new TrustManager[] { ctm }, new SecureRandom());
factory = sc.getSocketFactory();
}
catch (NoSuchAlgorithmException e)
{
Log.e(TAG, "createSocketFactory: failed to get SSLContext", e);
}
catch (KeyManagementException e)
{
Log.e(TAG, "createSocketFactory: failed to init SSLContext from CompositeTrustManager");
}
// createSslSocket
SSLSocket socket = null;
String addr = "172.31.106.60";
int port = 50001;
if (factory != null)
{
Log.d(TAG, "createSocketFactory - SUCCESS");
try
{
socket = (SSLSocket)factory.createSocket(addr, port);
Log.d(TAG, "createAltSocket - SUCCESS");
socket.setEnabledProtocols(new String[] { "TLSv1" });
socket.setEnabledCipherSuites(new String[] { "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" });
socket.setTcpNoDelay(true);
socket.setKeepAlive(true);
}
catch (IOException e)
{
Log.e(TAG, "createSslSocket - Couldn't create SSLSocket", e);
try
{
socket.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
finally
{
socket = null;
}
}
}
else
{
Log.d(TAG, "createSocketFactory - FAILED");
}
// testSslSocket
if (socket != null && socket.isConnected())
{
SSLSession session = socket.getSession();
if (session != null && session.isValid())
Log.d(TAG, "testSslSocket: SESSION SUCCESS");
else
Log.d(TAG, "testSslSocket: SESSION FAILED");
try
{
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
network_securiity_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="#raw/test_cert_chain"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.ssltesting">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:networkSecurityConfig="#xml/network_security_config">
<meta-data
android:name="android.security.net.config"
android:resource="#xml/network_security_config" />
test server
openssl s_server -tls1 -WWW -accept 50001 -cert test.crt -key mcv.key -state
In all working cases, the SSLSession is valid at the end of the test routine, and I get logging from the CertChainListener. However, when running this on my Android 7.0 device, all is quiet. I get no logging from the CertChainListener, the SSLSession is not valid, and I get the following on the server side:
Using default temp DH parameters
ACCEPT
SSL_accept:before/accept initialization
SSL3 alert write:fatal:handshake failure
SSL_accept:error in error
140386525526784:error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher:s3_srvr.c:1417:
ACCEPT
I am using SSLSocket to connect to a server. I want to use ssl SNI extension. I can use SSLParameter.setServerNames in java. But it appears in android it is not available till sdk 24. What are my options here?
I had the same problem, solved by using reflection.
Connect the socket using:
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) sf.createSocket(uri.getHost(), 443);
setSNIHost(sf, socket, uri.getHost());
SSLSession s = socket.getSession();
where setSNIHost is declared as:
public void setSNIHost(final SSLSocketFactory factory, final SSLSocket socket, final String hostname) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
Log.i(TAG, "Setting SNI via SSLParameters");
SNIHostName sniHostName = new SNIHostName(hostname);
SSLParameters sslParameters = socket.getSSLParameters();
List<SNIServerName> sniHostNameList = new ArrayList<>(1);
sniHostNameList.add(sniHostName);
sslParameters.setServerNames(sniHostNameList);
socket.setSSLParameters(sslParameters);
} else if (factory instanceof android.net.SSLCertificateSocketFactory) {
Log.i(TAG, "Setting SNI via SSLCertificateSocketFactory");
((android.net.SSLCertificateSocketFactory)factory).setHostname(socket, hostname);
} else {
Log.i(TAG, "Setting SNI via reflection");
try {
socket.getClass().getMethod("setHostname", String.class).invoke(socket, hostname);
} catch (Throwable e) {
Log.e(TAG, "Could not call SSLSocket#setHostname(String) method ", e);
}
}
}
I don't really remember where I copied the code for the reflection, I simply added the support for API 24.
Firstly,
I want to use session ticket in android, My code as follows:
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext cpmContext = SSLContext.getInstance("TLSv1.2");
cpmContext.init(null, null, null);
SSLSocket socket = (SSLSocket) cpmContext.getSocketFactory().createSocket(ip, port);
socket.setEnabledProtocols(socket.getEnabledProtocols());
socket.setEnabledCipherSuites(socket.getEnabledCipherSuites());
Class c = socket.getClass();
try {
Method m = c.getMethod("setUseSessionTickets",boolean.class);
m.invoke(socket,true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
SSLSession session = socket.getSession();
I capture the data blcok by tcpdump, the code can get "
TLSv1.2 224 New Session Ticket, Change Cipher Spec, Hello Request, Hello Request"
,so I think I get the session ticket, but when I reconnect to server, "session ticket "content of client hello is as follow:
"Extension:sessionTicket TLS
Type: SessionTicket TLS(0x0023)
length:0
Data:(0 bytes)"
it did not execute resume.
then I use SSLCertificateSocketFactory to create SSLSocket:
private Socket createSocketOnLine(final String ip, final int port) throws UnknownHostException, IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, KeyManagementException {
SSLCertificateSocketFactory sf = (SSLCertificateSocketFactory) SSLCertificateSocketFactory
.getDefault(30 * 1000);
SSLSocket socket = (SSLSocket) sf.createSocket(ip, port);
socket.setEnabledProtocols(socket.getEnabledProtocols());
socket.setEnabledCipherSuites(socket.getEnabledCipherSuites());
enableSessionTicket(sf, socket);
SSLSession session = socket.getSession();
return socket;
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public void enableSessionTicket(SSLCertificateSocketFactory sf, Socket socket) {
if (VERSION.SDK_INT > 17) {
sf.setUseSessionTickets(socket, true);
}
}
this code donot even enable session and the version of tls is always TLSv1.0,who can tell me how to enable it and set version of tls to be tlsv1.2?
PS:I test it on android 4.4 and L
Android's SSLCertificateSocketFactory is broken for you on some/many devices. It does not provide an interface/method for you to specify the enabled protocols. Instead, it simply uses the system default for the enabledProtocols. On earlier Android devices, that would be TLS and SSL3 and not TLSv1.2.
Because of the way it is implemented, you can't subclass it and attempt to override its behavior. There is no way for you to set the TLS protocol you want, let alone to set the ciphersuites that you may need to control.
Unfortunately, some of the other features of SSLCertificateSocketFactory are lost as well. For example, you can't enable SNI or set alpns protocols "officially" without it.
Thus, your solution will need to subclass SSLSocketFactory to provide your own socketfactory to control the settings you need as you do in your first code example. You can use your reflection trick above to enable session tickets in your own createSocket() method implementations.
This question already has answers here:
Https Connection Android
(11 answers)
Closed 7 months ago.
I am trying to connect to a URL from a my Android app in Andorid Version 4.1.1, and I get the error indicated in the Title of my question, but when I tried to connect the same URL from Andorid Version 4.0.4 or 3.1, all works fine.
The Code fragment :
try {
.
.
.
URL url = new URL(urlStr);
Log.i(TAG,"[ URL ] " + urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
int size = conn.getContentLength();
int responsecode = conn.getResponseCode();
Log.d(TAG, "Responsecode: " + responsecode);
.
.
.
} catch (Exception e) {
e.printStackTrace();
}
private static void trustAllHosts() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
System.out.println("IOException : HTTPSRequest::trustAllHosts");
e.printStackTrace();
}
}
But here i clear one thing is that "Maybe certificate is that self-signed certificates and is not including them in a KeyStore.
I do not understand why this excepton occure only in Android Verison 4.1.1 OS
Thanks.
FULL STACK TRACE
01-31 10:26:08.348: W/System.err(3158): java.io.IOException: Hostname <URL> was not verified
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection.java:223)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:446)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:130)
01-31 10:26:08.348: W/System.err(3158): at java.net.URLConnection.getHeaderFieldInt(URLConnection.java:544)
01-31 10:26:08.348: W/System.err(3158): at java.net.URLConnection.getContentLength(URLConnection.java:316)
01-31 10:26:08.348: W/System.err(3158): at libcore.net.http.HttpsURLConnectionImpl.getContentLength(HttpsURLConnectionImpl.java:191)
01-31 10:26:08.348: W/System.err(3158): at com.ih.util.HelpVideoServices$downloadTask.run(HelpVideoServices.java:172)
In case you are running with certificates that doesn't mean anything and you want to bypass them you also need to add a null host name verifier to make this code work
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new NullX509TrustManager()}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
And the code for the host:
import javax.net.ssl.HostnameVerifier ;
import javax.net.ssl.SSLSession;
public class NullHostNameVerifier implements HostnameVerifier {
#Override
public boolean verify(String hostname, SSLSession session) {
Log.i("RestUtilImpl", "Approving certificate for " + hostname);
return true;
}
}
This needs to run once, but if you are making changes to your connection object you might need to run it again.
In addition to #Noam's answer, this is a complete example:
/**
* 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.
*/
private static void disableSSLCertificateChecking() {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
// not implemented
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
// not implemented
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
Hope it helps
This might happen because the CN (Common Name) you have declared on your SSL does not mach the actual URL you are sending your HTTP request too.
If so, create a new SSL and enter the currect CN. That should fix the problem.
I experienced this problem in 4.1.1 and 4.1.2, using HTTPSUrlConnection.
After some poking around I discovered that it was because the Apache server I am dealing with has multiple virtual hosts serving https traffic, resulting in SNI issues in Android - at least prior to JellyBean (I have unconfirmed reports that it was working in JB).
In my case there were 3 virtual hosts serving https traffic:
mydomain.com
api.mydomain.com (the one I was trying to deal with)
admin.mydomain.com
Probing api.* with openssl_client like this:
openssl s_client -debug -connect api.mydomain.com:443
... always returned the root domain's certificate - buried in the output was something like:
Certificate chain
0 s:/OU=Domain Control Validated/CN=mydomain.com
...
... specifying the server name in the openssl_client command-line:
openssl s_client -debug -servername api.mydomain.com -connect api.mydomain.com:443
... returned the certificate I was expecting to see:
Certificate chain
0 s:/OU=Domain Control Validated/CN=api.mydomain.com
I was able to resolve the problem by moving the root domain virtual-host to a different physical host.
It seems that the Android HostnameVerifier can live with multiple sub-domain's side-by-side as virtual hosts, but having the root domain as a virtual-host in the same apache caused issues.
I am not a sys-admin/dev-ops and so it is possible that there are Apache config options that could have resolved the problem that I am not aware of.
Please note SSL Certificate work only by Domain not work by IP address.
if you use IP ,insert below code
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
if(hostname.equals("127.0.0.1"))
return true;
}
});
Android can't set up SSL connection, I suppose. Maybe your certificate for other host name, not the one you establish connection to. Read docs here and here.
This works better for me --> CHANGING StrictHostnameVerifier()
https://developer.android.com/reference/org/apache/http/conn/ssl/StrictHostnameVerifier
Example
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hv = new StrictHostnameVerifier();
return hv.verify("example.com", session);
}
};
Use Example https://developer.android.com/training/articles/security-ssl#java
// Tell the URLConnection to use our HostnameVerifier
URL url = new URL("https://example.org/");
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
urlConnection.setHostnameVerifier(hostnameVerifier);
From Amazon documentation:
Bucket Restrictions
"When using virtual hosted–style buckets with SSL, the SSL wild card certificate only matches buckets that do not contain periods. To work around this, use HTTP or write your own certificate verification logic."
The easiest way seems to create a unique bucket name without periods:
Instead of "bucketname.mycompany.com", something like "bucketnamemycompany" or any other DNS-compliant bucket name.
In Kotlin:
fun HttpsURLConnection.trustCert() {
try {
//Accepts every hostname
this.hostnameVerifier = HostnameVerifier { hostname, _ ->
println(hostname) //To be hardcoded/as needed
true
}
val trustMgr:Array<TrustManager> = arrayOf(object : X509TrustManager {
override fun checkClientTrusted(certs: Array<out X509Certificate>?, authType: String?) {}
override fun checkServerTrusted(certs: Array<out X509Certificate>?, authType: String?) {}
override fun getAcceptedIssuers(): Array<X509Certificate>? = null
})
this.sslSocketFactory = SSLContext.getInstance("TLS").also {
it.init(null, trustMgr, SecureRandom())
}.socketFactory
} catch (e: Exception) {
prinntln("SSL self-signed certificate processing error due to ${e.message}")
}
}
Usage:
val conn = URL(Uri.Builder().also {
it.scheme("https")
it.encodedAuthority("$serverIp:$serverPort")
}.build().toString()).openConnection() as HttpsURLConnection
conn.trustCert()
val respCode = conn.responseCode
if(respCode == 200) {
//do something (eg: read inputStream)
}