SSLPinning in Android Studio

Jyotishgher Astrology
By -
0

 SSL Pinning in Android Apps for Security

Implementing SSL pinning in an Android application ensures that your app only trusts specific SSL certificates, thereby preventing man-in-the-middle (MITM) attacks. Below are the steps to implement SSL pinning in an Android app using Java. This implementation assumes you have a backend based on LAMP (Linux, Apache, MySQL, PHP).

SSL Pinning in Android Apps

Steps to Implement SSL Pinning:

  1. Obtain Your SSL Certificate: First, obtain the SSL certificate (or public key) that your server is using. You can export it from your browser or use OpenSSL to fetch it.

  2. Add the Certificate to Your Project: Save your SSL certificate in the res/raw folder of your Android project. For example, if your certificate is named my_cert.cer, save it as my_cert.cer.

  3. Create a Custom TrustManager: You'll need a custom TrustManager to perform SSL pinning. This involves checking the certificate presented by the server against your pinned certificate.

  4. Set Up an OkHttpClient (Recommended): Using OkHttp or Volley for network operations allows easier integration of SSL pinning.

Sample Code

To implement SSL pinning in Android using Java with the Volley library and a LAMP (Linux, Apache, MySQL, PHP) backend, follow these steps:

1. Prepare the Server Certificate

  • Obtain your server's SSL certificate (server.crt) from the server.
  • Convert the .crt file to .der format:
    bash
    openssl x509 -inform PEM -in server.crt -outform DER -out server.der
  • Place the server.der file in the res/raw directory of your Android project.

2. Set Up SSL Pinning in Your Code

The Volley library does not directly support SSL pinning. You need to set up a custom HurlStack to manage SSL connections.


Step-by-Step Implementation

  1. Add Dependencies Ensure you have Volley included in your project:

    gradle
    implementation 'com.android.volley:volley:1.2.1'
  2. Create a Custom HurlStack Implement a custom HurlStack that uses the pinned certificate.

    java

    import android.content.Context; import com.android.volley.toolbox.HurlStack; import javax.net.ssl.SSLContext; 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 javax.net.ssl.SSLSocketFactory getPinnedSSLSocketFactory() { try { // Load the certificate CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream caInput = context.getResources().openRawResource(R.raw.server); // Replace 'server' with your file name Certificate ca = cf.generateCertificate(caInput); caInput.close(); // Create a KeyStore containing the trusted certificate KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("server", ca); // Create a TrustManager that trusts the certificate in our 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("Failed to set up SSL pinning", e); } } }
  3. Configure the Volley RequestQueue Use the custom HurlStack in the RequestQueue.

    java

    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; } }
  4. Make a Network Request Use the VolleySingleton to make requests.

    java

    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) { String url = "https://your-secure-server.com"; StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { System.out.println("Response: " + response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { System.err.println("Error: " + error.getMessage()); } }); // Add the request to the RequestQueue VolleySingleton.getInstance(context).getRequestQueue().add(stringRequest); } }

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Initialize NetworkRequest and make the pinned request
        NetworkRequest networkRequest = new NetworkRequest();
        networkRequest.makePinnedRequest(this);
    }
}

3. Test the Implementation

  • Success: The app should connect to the server successfully if the server provides the pinned certificate.
  • Failure: The app should reject connections if the certificate is invalid or tampered with.

4. Key Points

  • If the certificate changes, you will need to update the server.der file in your app.
  • Use HTTPS URLs in all your API requests to ensure encrypted communication.

This implementation ensures SSL pinning with the Volley library, protecting your app from MITM attacks. This ensures your NetworkRequest is seamlessly integrated into the MainActiviy

Tags:

Post a Comment

0Comments

Post a Comment (0)