~smartsunil.in
Security Topics
android

What is SSL Pinning ?

A practical introduction to analyzing certificate pinning in Android applications.

Jan 5, 2026·3 min read#Android#SSL Pinning#Mobile Security

What is SSL & TLS?

SSL = Secure Sockets Layer. TLS = Transport Layer Security.

SSL was the original protocol used to secure network communication between a client and server. TLS is the modern protocol used to secure communications.

What is SSL/TLS certificate pinning?

Normal TLS says "I trust certificates that chain to an acceptable trusted CA." Certificate pinning adds another restriction: "For this particular server, I expect this specific certificate or public key."

Normal validation
 
api.example.com
      ↓
Certificate
      ↓
Trusted CA
      ↓
VALID

Pinning adds:

Certificate
     ↓
Trusted CA
     +
Expected public key/certificate
     ↓
VALID

Why was certificate pinning introduced?

Consider a normal CA ecosystem. Your device may trust hundreds of certificate authorities.

Android trust store
 
CA 1
CA 2
CA 3
CA 4
CA 5
...
CA N

Suppose the legitimate server has:

api.example.com
      ↓
Certificate
      ↓
CA X

If another trusted CA can issue a certificate for: api.example.com, then ordinary CA validation could potentially accept it.

Pinning says:

I don't merely trust "any valid certificate."
I expect THIS certificate/public key.

SSL Pinning Implementation:

Android framework/config ( network configure xml file ) Java/Kotlin custom ( application code java level ) HTTP library ( Okhttp or similar ) Native ( .so libraries ) Hybrid ( Java + JNI + Native )

How would your assessment identify Java pinning?

During static analysis, you would look for things such as:

CertificatePinner
TrustManager
X509TrustManager
checkServerTrusted
SSLContext
SSLSocketFactory
KeyStore
CertificateFactory
HostnameVerifier

And for custom logic:

MessageDigest
SHA-256
X509Certificate
getPublicKey()
checkServerTrusted()

The presence of:

getPublicKey() combined with: SHA-256 and a hardcoded value is particularly interesting.

Conceptually:

getPublicKey()
      ↓
MessageDigest SHA-256
      ↓
compare against hardcoded value

That strongly suggests public-key pinning logic.

Native-level SSL pinning

An Android application doesn't have to perform TLS entirely in Java/Kotlin. It can use: Java/Kotlin -> JNI -> Native C/C++ -> TLS library -> Socket The native library might use a TLS implementation such as:

BoringSSL
OpenSSL
mbedTLS
custom TLS implementation
The exact implementation depends on the application.

Native pinning architecture

Android application
        |
        ↓
       JNI
        |
        ↓
   libnative.so
        |
        +---- TLS initialization
        |
        +---- certificate loading
        |
        +---- verification callback
        |
        +---- pin comparison
        |
        ↓
    TLS library
        |
        ↓
     socket

The pinning logic could therefore be completely absent from Java. You might search the APK's: for native libraries. lib/arm64-v8a/ lib/armeabi-v7a/ lib/x86_64/

Native certificate verification , conceptually

certificate = get_peer_certificate();
 
public_key = extract_public_key(certificate);
 
hash = sha256(public_key);
 
if (memcmp(hash, expected_pin, 32) != 0) {
    return VERIFY_FAILED;
}
 
return VERIFY_SUCCESS;

The actual implementation might be heavily optimized, obfuscated, split between several functions, or delegated to a TLS library callback.

Related Research