Fork us on GitHub

Certificate Verification, Avoid SSL Pinning Vulnerability

New cn1lib to verify SSL server certificates
Certificate Verification, Avoid SSL Pinning Vulnerability

Certificate Verification, Avoid SSL Pinning Vulnerability

Certificate pinning is a security measure designed to thwart potentially dangerous and complex attacks. Since those sort of attacks are pretty hard to execute it’s a security measure that is probably unnecessary for most developers. However, if you are building an application for a very sensitive industry (e.g. Government, Banking etc.) you might be required to include this defensive measure.

When we connect to an HTTPS server our client checks the certificate on the server. If the certificate was issued by a trusted certificate authority then the connection goes thru otherwise it fails. Let’s imagine a case where I’m sitting in a coffee shop connected to the local wifi, I try to connect to gmail to check my email. Since I use HTTPS to Google I trust my connection is secure.

What if the coffee shop was hacked and the router is listening in on everything?

So HTTPS is encrypted and the way encryption works is thru the certificate. The server sends me a certificate and we can use that to send encrypted data to it.

What if the router grabs the servers certificate and communicates with Google in my name?

This won’t work since the data we send to the server is encrypted with the certificate from the server.

So what if the router sends its own "fake certificate"?

That won’t work either. All certificates are signed by a "certificate authority" indicating that a google.com certificate is valid.

What if I was able to get my fake certificate authorized by a real certificate authority?

That’s a problem!

It’s obviously hard to do but if someone was able to do this he could execute a "man in the middle" attack as described above. People were able to fool certificate authorities in the past and gain fake certificates using various methods so this is possible and probably doable for any government level attacker.

Certificate Pinning

This is the attack certificate pinning (or SSL pinning) aims to prevent. We code into our app the "fingerprint" of the certificate that is "good" and thus prevent the app from working when the certificate is "fake". This might break the app if we replace the certificate at some point but that might be reasonable in such a case.

To do this we introduced a new cn1lib. that fetches the certificate fingerprint from the server, we can just check this fingerprint against a list of "authorized" keys to decide whether it is valid. You can install the SSLCertificateFingerprint from the extensions section in Codename One Settings and use something like this to verify your server:

if(CheckCert.isCertCheckingSupported()) {
    String f = CheckCert.getFingerprint(myHttpsURL);
    if(validKeysList.contains(f)) {
        // OK it's a good certificate proceed
    } else {
       if(Dialog.show("Security Warning", "WARNING: it is possible your commmunications are being tampered! We suggest quitting the app at once!", "Quit", "Continue")) {
          Display.getInstance().exitApplication();
       }
    }
} else {
    // certificate fingerprint checking isn't supported on this platform... It's your decision whether to proceed or not
}

Notice that once connection is established you don’t need to verify again for the current application run.

Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.