Skip to content
Codenotary
All posts

Certificate and Public Key Pinning Made Easy with immudb Vault

Security for data in transit can never be underestimated. There are several threats such ARP cache poisoning, DNS poisoning and other man-in-the-middle type of attacks for IPv4 world to lure client into seamless communication with the wrong destination. It can become even global with malicious configurations of Border Gateway Protocol (BGP) at Internet Service Provider (ISP) level as the history has already proven.

See how Cloudflare describes impact on BGP Hijacking. BGP can easily break the Internet when and have a significant impact on security. Celer Bridge incident causing a damage of $235,000 in cryptocurrency is just one of the recent cases. OWASP Top 10 Web Application Security Risks is a number one checklist that the developers should follow when creating new software. They put Cryptographic Failures as the 2nd most important item next to Broken Access Control in their security checklist.

Most of the modern and up to date services attempt to use certificates instead of passwords to authenticate and authorize the clients up on connection. Some good examples are web sites establishing Transport Layer Security (TLS) based connections as well as our well known Secure Socket Shell (SSH) interface for remote administration embedding Public/Private key authentication.

brett-jordan-D44kHt8Ex14-unsplash

Certificate pinning is one of the good practices the industry has adopted to strengthen the trust for the destination we communicate with. It sounds as good as it is but as always there are a few caveats and one of them is the maintenance. As we know certificates expire and when they do we would need to update the actual Public Key at your client's end and the worst part of that is that it is so easily to forget to do it. Even more if you have acknowledged that it is part of your planned activities it might be challenging enough if you have let's say a mobile app which needs to be distributed with the updated embedded pinned Public Key within the next day so that the service for your clients is not interrupted.

Before we go further on let's understand what is Certificate Pinning. OWASP gives a decent explanation of Certificate and Public Key Pinning but to summarize it we could just say that it is a way to verify the destination endpoint by comparing their published fingerprint to what we have saved on our end way before.

A Typical Scenario of Implementing Certificate and Public Key Pinning

Let's walk through a typical scenario where you would try to implement a Certificate Pinning.

  1. You would start with retrieving the Public Key from your desired endpoint service

    The following will retrieve the full certificate chain
    echo "Get HTTP/1.0" | openssl s_client -showcerts -connect cloud.opvizor.com:443 > opvizor-cloud.pem

    Let's base64 encode everything
    cat opvizor-cloud.pem | base64 -w0

    If you would like to pin only the public key use the following command line
    openssl s_client -connect cloud.opvizor.com:443 | openssl x509 -pubkey -noout -out opvizor-cloud-key.pub

    Base64 encode it with
    cat opvizor-cloud-key.pub | base64 -w0

  2. The public key retrieved is then embedded in your service / application / client code base or provided as a runtime parameter.
  3. Up on making a connection with the destination you would once again retrieve the actual Public Key
  4. Finally a comparison between the retrieved Public Key and the one you saved in the begging is made. If they match you are save to do a further data exchange otherwise the connection would be terminated immediately. 

    Two public keys can be compared with the openssl client and md5 checksum
    cat opvizor-cloud-key.pub | openssl md5
    MD5(stdin)= 10aa1912a2077692bd163d14355eea99


  5. Here the caveat comes - you need to re-embed the certificate once again into the client (be it a script, a service or a mobile application) whenever it gets updated at the other end.

 

Certificate and Public Key Pinning with immudb Vault

Immudb Vault is a service with an immutable database underneath that guarantees immutability for the data saved there by a mathematical proof. It can be used as an independent trusted authority for saving Certificates and Public Keys easily. Let's walk through the steps what you would take to adjust the typical way of doing Certificate Pinning.

  1. You can't escape the retrieval of the certificate so you still start with pulling it from the endpoint.

    openssl s_client -connect cloud.opvizor.com:443 | openssl x509 -pubkey -noout -out opvizor-cloud-key.pub
    depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
    verify return:1
    depth=1 C = US, O = Let's Encrypt, CN = R3
    verify return:1
    depth=0 CN = cloud.opvizor.com
    verify return:1

  2. Save it in immudb Vault

    certificate_endpoint="cloud.opvizor.com:443"

    certificate_object=$(cat opvizor-cloud-key.pub | base64 -w0)
    json=$(printf '{"certificate_endpoint":"%s","certificate_object":"%s"}\n' "$certificate_endpoint" "$certificate_object")
    curl -X 'PUT'   'https://vault.immudb.io/ics/api/v1/ledger/default/collection/default/document' \
      -H 'accept: application/json' \
      -H 'X-API-Key: ...' \
      -H 'Content-Type: application/json' \
      -d "$json"

  3. In your client, be it an iOS / Android app, CLI client or a Web App, all you need to do is the retrieve the latest from your immudb Vault account and you are good to gocertificate_object=$(curl -sX 'POST'  'https://vault.immudb.io/ics/api/v1/ledger/default/collection/default/documents/search' \-H 'accept: application/json' \-H 'X-API-Key: …' \-H 'Content-Type: application/json' \-d '{"page":1,"perPage":100}' | jq -r '.revisions[0].document.certificate_object' )

    Note that we always recommend to use the READ ONLY API KEY (PUBLIC) for data retrieval and verification

     

  4. To compare what the site returns to what we have stored in immudb Vault we write a simple bash script (of course any other language is capable to do the same)

    #!/bin/bash
     
    what_site_provides=$(openssl s_client -connect cloud.opvizor.com:443 | openssl x509 -pubkey -noout | openssl dgst -sha1 -binary | xxd -p)

    trusted_from_vault=$(curl -sX 'POST' 'https://vault.immudb.io/ics/api/v1/ledger/default/collection/default/documents/search' \
    -H 'accept: application/json' \
    -H 'X-API-Key: …' \
    -H 'Content-Type: application/json' \
    -d '{"page":1,"perPage":100}' | jq -r '.revisions[0].document.certificate_object | openssl dgst -sha1 -binary | xxd -p)
     
    if [ "$what_site_provides" = "$trusted_from_vault" ]; then
    echo "We have a match"
    else
    echo "No match"
    fi

Conclusions

Security can easily be over-engineered making it hard to maintain to ensure availability of the resources that we protect. With immudb Vault we strive to bring an easy to use and easy to understand immutable cloud database providing endless use cases for secure and trusted data exchange and identity verification. 

Using immudb Vault as a central trusted authority for your public key pinning makes it much easier to verify your communication endpoints compared to classic certificate pinning. No more need to do unnecessary maintenance replacing your embedded keys, recompiling the services or re-distributing mobile applications to users.  Push your public keys to immudb Vault and always retrieve the latest for comparison.

Start your Certificate and Public Key Pinning with immudb Vault today, and step into the future of secure and trusted communication.

Your ticket for immudb Vault