Reputation: 4279
in my application I am trying to do a HTTPS POST request to my server. However, I keep getting SSLHandshakeException - Chain chain validation failed, all the time. I tried to send a request using POSTMAN and I got a response from the server. What can be causing this error when I try to send the request from the application?
Here a code snippet where I try to send the post request:
public static JSONObject getDataLibConfiguration(Context context) throws HttpRequestException {
int statusCode = 0;
JSONObject commonInformation;
HttpsURLConnection connection = null;
try {
commonInformation = ConfigurationProcessor.getCommonInformation(context);
if (commonInformation == null) {
return null;
}
URL url = new URL(BuildConfig.SERVER_CONFIG_URL);
if (BuildConfig.DEBUG) {
LogUtils.d(TAG, "url = " + url.getPath());
}
connection = getHttpsConnection(url);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Content-Encoding", "gzip");
byte[] gzipped = HttpUtils.gzip(commonInformation.toString());
cos = new CountingOutputStream(connection.getOutputStream()); //<-- This is where I get the exception
cos.write(gzipped);
cos.flush();
statusCode = connection.getResponseCode();
// More code her
}
private static HttpsURLConnection getHttpsConnection(URL url) throws IOException, GeneralSecurityException {
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
MatchDomainTrustManager myTrustManager = new MatchDomainTrustManager(url.getHost());
TrustManager[] tms = new TrustManager[]{myTrustManager};
sslContext.init(null, tms, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
connection.setSSLSocketFactory(sslSocketFactory);
} catch (AssertionError ex) {
if (BuildConfig.DEBUG) {
LogFileUtils.e(TAG, "Exception in getHttpsConnection: " + ex.getMessage());
}
LogUtils.e(TAG, "Exception: " + ex.toString());
}
return connection;
}
Upvotes: 96
Views: 95835
Reputation: 110
In my case I had to add trusted certificate. I got the certificate from Chrome by visiting my website and clicking the options on the left to the url field and navigating through security to view that certificate and in the preview on the second tab called details you click export button on the bottom and I chose base64 encoded ASCII *.crt file. Added the file into resources/raw folder.
I updated the manifest.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
...
android:networkSecurityConfig="@xml/network_security_config" >
...
</application>
</manifest>
and then defined the network_security_config.xml file in resources/xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">your_domain.com</domain>
<trust-anchors>
<certificates src="@raw/your_domain_cert"/>
</trust-anchors>
</domain-config>
</network-security-config>
and it immeditately worked.
Upvotes: 0
Reputation: 12609
In my case SSL was not implemented and s
was added by mistake after http
in the URL.
Remove s
from the URL and it worked.
https://example.com updated to http://example.com
Upvotes: 0
Reputation: 2092
In my case the date/ time was ok and I was still getting the exception. I restarted my device and the problem went away. Hope it helps someone if all the above fails.
Upvotes: 2
Reputation: 4463
In my case it was wrong date on the phone.
Fixing the date resolved an issue
Upvotes: 267
Reputation: 67
If you use android emulator, you can wipe data and run again, it works
Upvotes: 2
Reputation: 3265
In my case, the issue was with the phone date. So please check it, set to automatic.
Upvotes: 15
Reputation: 10057
In my case, I fetch this issue on Android Emulator. When I clear emulator cache has resolved the issue.
Upvotes: 35
Reputation: 338
I fixed this error by resetting my emulator date and time. My server is working fine just I changed the date and time of my emulator as current server time zone.
Upvotes: 6
Reputation: 81
@Yash Bhardwaj in the comment on @Vadim answer said that the problem was in Glide framework. I faced the same problem: Https requests to server using Ktor framework were all successful, but when Glide tried to load image from the same server, it faced the SSLHandshakeException
.
To solve this issue you should look here: Solve Glide SSLHandshakeException.
To make a deal with @GlideModule
annotation you should import kapt
plugin and add these dependencies into your app build.gradle
:
implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
Upvotes: 1
Reputation: 700
My date and time were correct, but I didn't have "Use Network Provided Time checked" in my system settings.
I fixed this issue by going to Settings > Date and Time > Check "Use network-provided time" and also check "Use network-provided time zone".
Then this error went away.
Upvotes: 15
Reputation: 601
If you're using an emulated device it may solve the problem if you just 'Cold Boot' it.
Sometimes the date on those things can get stuck if you let them run for some time, which results in this expired-certificate-problem.
Upvotes: 60
Reputation: 614
If anyone come across this issue pertaining to specific device, then the reason should be because of incorrect date set in the device.
Upvotes: 8
Reputation: 101
public static void trustEveryone() {
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) { // should never happen
e.printStackTrace();
}
}
or check system date of your device - I had this Exception when I tried to connect with wrong date!..
Upvotes: 10