SSL Pinning Failed in Android

Jyotishgher Astrology
By -
6 minute read
0

 SSL Pinning Failed in Android

Your SSL Pinning implementation looks mostly correct, but if it’s suddenly failing, there are a few key areas to check and fix.

SSL Pinning Failed in Android

Possible Causes & Fixes

✅ 1. Certificate Mismatch (Most Common Issue)

  • If your server recently renewed or changed its SSL certificate, the old pinned certificate in res/raw/certificate.pem no longer matches.
  • Fix: Get the latest certificate from your server and replace the certificate.pem file.

How to Get the Latest Certificate?

Run this command in a terminal (replace yourdomain.com):

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com | openssl x509 -outform PEM > certificate.pem

Then, update your res/raw/certificate.pem file.

2. Incorrect Certificate File Format

  • Ensure your certificate file is in PEM format and stored in res/raw/certificate.pem.
  • Fix: Convert DER to PEM format using:
  • openssl x509 -inform DER -in certificate.der -out certificate.pem

3. Check PinningHurlStack Implementation

🔹 Replace Your PinningHurlStack.java With This Version:

import android.content.Context;
import com.android.volley.toolbox.HurlStack;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
public class PinningHurlStack extends HurlStack {    private final Context context;   
 public PinningHurlStack(Context context) {
this.context = context;
}
@Override
protected HttpURLConnection createConnection(URL url) throws java.io.IOException
{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (connection instanceof javax.net.ssl.HttpsURLConnection)
 {

  ((javax.net.ssl.HttpsURLConnection)
 connection).setSSLSocketFactory(getPinnedSSLSocketFactory());
}
return connection;
}
private SSLSocketFactory getPinnedSSLSocketFactory() {
try {
// Load certificate from res/raw/certificate.pem
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.certificate);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
// Create a KeyStore and add the certificate
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
  // Create a TrustManager that trusts the KeyStore
TrustManagerFactory tmf =
 TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// Create an SSLContext that uses the TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
 return sslContext.getSocketFactory();   
     } catch (Exception e) {
throw new RuntimeException("SSL Pinning Failed: " + e.getMessage(), e);
}
}
}

Fixes Issues:

  • Ensures proper certificate loading.
  • Uses better error handling (throw new RuntimeException helps debugging).
  • Properly closes input streams to prevent leaks.

4. Fix VolleySingleton

🔹 Update VolleySingleton.java to Ensure Secure Requests

import android.content.Context;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class VolleySingleton {
private static VolleySingleton instance;
private RequestQueue requestQueue;
private final Context context;
private VolleySingleton(Context context) {
this.context = context.getApplicationContext();
requestQueue = Volley.newRequestQueue(context, new PinningHurlStack(context));
}
public static synchronized VolleySingleton getInstance(Context context) {
if (instance == null) {
instance = new VolleySingleton(context);
}
return instance;
}
public RequestQueue getRequestQueue() {
return requestQueue;
}
}

Ensures all requests go through PinningHurlStack.

5. Improve NetworkRequest Handling

🔹 Fix NetworkRequest.java

import android.content.Context;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
public class NetworkRequest {
public void makePinnedRequest(Context context, NetworkCallbackActivity callback)
{
StringRequest stringRequest = new StringRequest(Request.Method.GET,
URL_SSL_PINNING_CERTIFICATE,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
System.out.println("Response: " + response);
callback.onSuccess();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
System.err.println("SSL Pinning Error: " +
(error.getMessage() != null ? error.getMessage() : "Unknown error"));
error.printStackTrace();
callback.onFailure("SSL Pinning Failed!");
Toast.makeText(context, "SSL Pinning Failed!",
Toast.LENGTH_SHORT).show();
}
});
// Add to secure request queue
VolleySingleton.getInstance(context).getRequestQueue().add(stringRequest);
}
}

Ensures error messages are properly handled and logged.

Final Checklist

1. Is the Certificate Updated?

  • Run:
  • openssl s_client -connect yourdomain.com:443 -servername yourdomain.com | openssl x509 -outform PEM > certificate.pem
  • Replace old res/raw/certificate.pem file.

2. Is the Certificate in PEM Format?

  • Run:
  • openssl x509 -inform DER -in certificate.der -out certificate.pem

3. Are You Using the Correct TrustManager & SSL Context?

  • Implement the updated PinningHurlStack.java.

4. Are You Using the Correct Singleton Pattern?

  • Ensure VolleySingleton.java properly initializes requests with SSL Pinning.

5. Debugging?

  • If SSL Pinning still fails, log the stack trace using:
  • error.printStackTrace();

Check for javax.net.ssl.SSLHandshakeException—this confirms a certificate mismatch.

Summary

If SSL Pinning suddenly fails, it’s 99% a certificate issue.

  • First, update the pinned certificate (Step 1).
  • Second, confirm PEM format (Step 2).
  • Third, use correct SSL initialization (Steps 3 & 4).

After these fixes, SSL Pinning will work securely again!

Tags:

Post a Comment

0Comments

Post a Comment (0)