This is an implementation of converting the a PEM certificate's Subject Public Key Info (SPKI) into a pin.
The pin directive (as indicated in the IETF's RFC 7469 Sesction 2.1.1) is a shown in the diagram below where the token is the name of the hashing algorithm.
Currently only SHA256
is supported.
A full example being: pin-sha256="8RoC2kEF47SCVwX8Er+UBJ44pDfDZY6Ku5mm9bSXT3o=";
. However, the Python
code in this repository outputs the PKP in the format: sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
.
This is consistent with how pins are accepte in other languages/frameworks, such as OkHttp3
(see the Add()
method for its CertificatePinner.Builder class
)
In section 2.4 of the RFC the SPKI Fingerprint is defined as:
The output of a known cryptographic hash algorithm whose input is the DER-encoded ASN.1 representation of the Subject Public Key Info (SPKI) of an X.509 certificate.
A pin is defined as:
The combination of the known algorithm identifier and the SPKI Fingerprint computed using that algorithm.
- To change the implementation to use M2Crypto and be able to install/run it on Windows, see:
NOTE: There are warnings against using public key pinning due to its risks:
- Ars Technica article: How to hurricane-proof a Web server
- SCOTT HELME: I'm giving up on HPKP
- Smashing Magazine: Be Afraid Of HTTP Public Key Pinning (HPKP)
- Is HTTP Public Key Pinning Dead?
Here are some resources I used:
- https://www.pyopenssl.org/en/stable/api/crypto.html#x509-objects
- https://security.stackexchange.com/questions/84499/how-to-add-certificate-pinning-for-a-certain-domain-to-my-web-browser
- https://www.ssllabs.com/ssltest/analyze.html?d=appmattus.com
- https://cryptography.io/en/latest/x509/reference/
- https://stackoverflow.com/questions/7689941/how-can-i-retrieve-the-tls-ssl-peer-certificate-of-a-remote-host-using-python
- https://stackoverflow.com/a/36186060/6288413
- https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey