Pinning SSL Certs with cURL from PHP

I wanted to do some REST client stuff in PHP with cURL today. It has the neat CURLOPT_PINNEDPUBLICKEY option that one can use to set the certificate fingerprint. Unfortunately its a bit cumbersome, as one needs to enter the fingerprint in base64, instead of just the format the browser displays if you look at the cert directly (e.g.: 529728d7c43746c0bb02ac4a4c3bffb7028ac1591ecb08b6a0721a660aa1d3ce).

Luckily we can just get the correct fingerprint format using this one command:

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

You can download the cert using Chrome or Firefox and then use the openssl command above to get the correct base64 formatted string (e.g.: WcHR5sNo7T3ZDL6b/dLgFFETh4tdkm8SAHXfqKLo9wo=).

The same works for the Symfony HTTP Client library that also expects the same format (that is further passed on to cURL) for the peer_fingerprint options entry. The official docs unfortunately do not mention this at all and just replace the formatted value by ‘…’. Oh well.

Published by

Kordian Bruck

I'm a TUM Computer Science Alumni. Pizza enthusiast. Passionate for SRE, beautiful Code and Club Mate. Currently working as an SRE at Google. Opinions and statements in this blog post are my own.