Skip to content

Instantly share code, notes, and snippets.

@kousu
Created November 28, 2020 06:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kousu/d3fd6e32c66f89914995d113b0a3a850 to your computer and use it in GitHub Desktop.
Save kousu/d3fd6e32c66f89914995d113b0a3a850 to your computer and use it in GitHub Desktop.
http cert pinning

Generate certificate pins for your apps.

#!/usr/bin/env bash
# pin.sh
set -eo pipefail
if [ -z "$1" ]; then
cat <<DOCS
usage: pin.sh CERT.pem [CERT.pem ...]
Create x509 certificate pins for use with libraries like OkHttp (https://square.github.io/okhttp/4.x/okhttp/okhttp3/-certificate-pinner/)
Only supports sha256 pins. Some implementations support sha1, but that is always the weaker choice, cryptography-wise.
References:
https://tools.ietf.org/html/rfc7469
https://www.imperialviolet.org/2011/05/04/pinning.html
https://serverfault.com/questions/911823/how-to-extract-public-key-from-a-der-file-in-subjectpublickeyinfo-format
example:
$ openssl s_client -showcerts -connect google.com:443 </dev/null > google.pem
depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.google.com
verify return:1
DONE
$ ./pin.sh google.pem
sha256/XL7jJ71nBgDA7ya7f7ty0JCgcuoMzHOLAl9t8SnrjFY=
DOCS
exit 1;
fi
pin() {
CERT="$1"
# openssl is cranky and difficult; for a not-too-untrue summary of the situation: http://mirrors.dotsrc.org/fosdem/2014/Janson/Sunday/NSA_operation_ORCHESTRA_Annual_Status_Report.webm
# nevertheless, it is fast and pretty well tested, so let me explain what is happening here.
# 1. There are two possible input formats: a certificate in .pem format and a certificate in .der format.
# since we don't know which, try them both
# 1b. -noout doesn't mean "no out", it means "disable the normal default output"; -pubkey causes a second, unrelated, piece of output to come out.
if HASH=$((openssl x509 -in "$CERT" -inform pem -pubkey -noout ||
openssl x509 -in "$CERT" -inform der -pubkey -noout) 2>/dev/null |
# the -pubkey format is always pem, but we need der, so convert it
openssl enc -base64 -d |
# now hash it
openssl dgst -sha256 -binary |
# and make it binary safe
openssl enc -base64; ); then
echo "sha256/$HASH"
else
echo "$CERT couldn't be hashed. Is it in the right format?" >&2
exit 1
fi
}
while [ -n "$1" ]; do
pin "$1"
shift
done
@kousu
Copy link
Author

kousu commented Nov 28, 2020

🦁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment