Search code examples
androidopensslokhttpandroid-securitypublic-key-pinning

Is it necessary to store SPKI hash securely in android?


I'm trying to enable public key pinning since I don't want to release updates for every certificate renewal provided I'll use the same CSR every time.

I generated the hash with this script.

#!/bin/bash
certs=`openssl s_client -servername $1 -host $1 -port 443 -showcerts </dev/null 2>/dev/null | sed -n '/Certificate chain/,/Server certificate/p'`
rest=$certs
while [[ "$rest" =~ '-----BEGIN CERTIFICATE-----' ]]
do
 cert="${rest%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"
 rest=${rest#*-----END CERTIFICATE-----}
 echo `echo "$cert" | grep 's:' | sed 's/.*s:\(.*\)/\1/'`
 echo "$cert" | openssl x509 -pubkey -noout | 
     openssl rsa -pubin -outform der 2>/dev/null | 
     openssl dgst -sha256 -binary | openssl enc -base64
done

Hope it'll not change!

I'm using okhttp3 certificatePinner to embed this in retrofit.

private CertificatePinner getCertificatePinner() {
    return new CertificatePinner.Builder()
            .add("<api base URL>",
                    "sha256/<the key>")
            .build();
}

My ask is like should we store it in the application securely with NDK or something? Since everyone can generate this key if they know the API base URL.

Not sure if this is a dumb question.

Thanks


Solution

  • It's not a secret, you can store the certificate pin freely. But most advice is against using Certificate Pinning unless you know what you are doing and what your security team certificate policy is. Getting it from a live server is asking for trouble for when they rotate certificates or switch to backups.