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

28,269

Solution 1

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.

Solution 2

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="

Solution 3

Use this to get base64 sha256 of online https url:

openssl s_client -connect google.com:443 < /dev/null 2>/dev/null | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
Share:
28,269

Related videos on Youtube

CommonsWare
Author by

CommonsWare

Mark Murphy, founder of CommonsWare, writes a lot. Books From 2008 through 2021, Mark wrote a series of books on Android app development. These books are now available for free download from the CommonsWare site. His most recent books have been focused on second-generation Android app development (Kotlin and the Android Jetpack): Elements of Android Jetpack, a new introductory book on Android app development, focused on second-generation techniques. Exploring Android, a series of step-by-step tutorials for building an Android app from scratch. This book demonstrates app development using Kotlin, coroutines, and the Jetpack libraries. Elements of Android Room, to help you incorporate Google's reactive object wrapper around SQLite. Elements of Android R, to help you deal with the changes introduced by Android 11 (code-named "R"). It covers everything from scoped storage changes to data access auditing to sharing UIs between apps to bubbles. Elements of Kotlin, a guide to the Kotlin programming language, which is rapidly gaining in popularity for Android app development. Elements of Kotlin Coroutines, exploring Kotlin's new first-class reactive programming system. In the beginning, Android development was focused on Java and, partially, on the Android Support Library. Mark's earliest books share that focus: The Busy Coder's Guide to Android Development, the first and largest book on Android app programming Android's Architecture Components GraphQL and Android Things Other Than Books He runs the jetc.dev weekly newsletter for Jetpack Compose. Heck, he even has a blog. All code in Stack Overflow questions, answers, or comments written by Mark Murphy are hereby licensed under the Apache Software License 2.0, unless otherwise noted where that code appears on Stack Overflow.

Updated on July 28, 2021

Comments

  • CommonsWare
    CommonsWare almost 3 years

    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?

  • Devy
    Devy over 5 years
    I just want to add that the oneliner above is assuming cert.crt is in PEM format. If your have the DER format of the certificate, you can do cat cert.der | openssl dgst -sha256 -binary | openssl enc -base64 without having to do a double conversion.
  • Gal Rom
    Gal Rom about 4 years
    Perfect it works, in my case It was in DER format so as you suggested I added the -inform der. This is the command I used that generated the proper value: openssl x509 -inform DER -in TheCertificate.cer -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
  • sanjeev kumar
    sanjeev kumar about 4 years
    Hi can you please let me know where i need to keep the certificate file for executing this command @GalRom

Related