Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do We Generate a Base64-Encoded SHA256 Hash of SubjectPublicKeyInfo of an X.509 Certificate, for Android N Certificate Pinning?

The documentation in the N Developer Preview for their network security configuration offers these instructions:

Certificate pinning is done by providing a set of certificates by hash of the public key (SubjectPublicKeyInfo of the X.509 certificate). A certificate chain is then only valid if the certificate chain contains at least one of the pinned public keys.

The XML that they show is broken (missing a closing tag), but otherwise suggests that the hash is SHA256 and encoded base64:

<?xml version="1.0" encoding="utf-8"?> <network-security-config>     <domain-config>         <domain includeSubdomains="true">example.com</domain>         <pin-set expiration="2018-01-01">             <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>             <!-- backup pin -->             <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>     </domain-config> </network-security-config> 

How do we create such a hash?

I tried the approach in this gist, but openssl x509 -inform der -pubkey -noout is not liking my CRT file. I cannot readily determine if the problem is in the CRT file, the instructions, my version of openssl, or something else.

Does anyone have a known good recipe for creating this hash?

like image 749
CommonsWare Avatar asked Mar 22 '16 19:03

CommonsWare


People also ask

What is Base64 encoded x 509?

509 digital certificate encoded in binary – 1's and 0's. Base64 is a binary-to-text encoding scheme, so a PEM file, which is a Base64 encoded DER file, is that same X. 509 certificate, but encoded in text, which (remember!) is represented as ASCII.

What is SHA256 Base64?

base64sha256 computes the SHA256 hash of a given string and encodes it with Base64. This is not equivalent to base64encode(sha256("test")) since sha256() returns hexadecimal representation. The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied as defined in RFC 4634.


2 Answers

openssl x509 -in cert.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

You may need to add -inform der to the first command if cert.crt is in DER form rather than in PEM form.

like image 75
Alex Klyubin Avatar answered Nov 08 '22 19:11

Alex Klyubin


For setting up Android network-security-config pinning for a host that is already live, I prefer gnutls-cli (GnuTLS Client). It outputs a host's certificate info in a form where the sha256 is readibly copy-pasteable as base64 encoded. For example:

$ gnutls-cli stackoverflow.com </dev/null <...>  - subject `CN=*.stackexchange.com,O=Stack Exchange\, Inc.,L=New York,ST=NY,C=US', issuer `CN=DigiCert SHA2 High Assurance Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US', serial 0x0e11bbd70d54b710d0c6f540b6b52ca4, RSA key 2048 bits, signed using RSA-SHA256, activated `2016-05-21 00:00:00 UTC', expires `2019-08-14 12:00:00 UTC', pin-sha256="2zKehMv7KtnGBz1d2U0bFrAOKb1aWWlrG9a0BzrOvwA=" 
like image 27
laalto Avatar answered Nov 08 '22 18:11

laalto