security - How to verify the SSL fingerprint by command line? (wget, curl, ...)

  • James Mitch

    Using a command line website downloader, such as wget, curl or any other one... In a script...

    I have the SHA-1 and the SHA-256 certficate fingerprint of a website. Due to security concerns (1) (2), I don't want to use the public SSL certificate authority system. The fingerprint must be hard coded.

    Can a wget like application check the SSL fingerprint?

    wget does not have such a functionality. (3)

    Using wget --ca-certificate or curl --cacert I would have to run my own local certificate authority, which I'd like to prevent, because that adds a lot complexity. It's also ultra difficult and no one did that ever before. (4)

    Isn't there any tool, like
    download --tlsv1 --serial-number xx:yy:zz --fingerprint xxyyzz

    The solution must of course not be vulnerable to TOCTOU. (5) The MITM could let return a valid fingerprint for the openssl client request and tamper with the following wget request.

  • Answers
  • James Mitch


    Install required software:

    apt-get install ca-certificates curl

    Download the public SSL certificate:

    openssl s_client -connect -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt >./x.cert </dev/null

    Or better:

    echo -n | openssl s_client -connect -CAfile /usr/share/ca-certificates/mozilla/DigiCert_Assured_ID_Root_CA.crt | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./torproject.pem

    Get SHA-1 fingerprint:

    openssl x509 -noout -in torproject.pem -fingerprint -sha1

    Get SHA-256 fingerprint:

    openssl x509 -noout -in torproject.pem -fingerprint -sha256

    Manually compare SHA-1 and SHA-256 fingerprints with FAQ: SSL.


    Optionally render the ca-certificates useless for testing purposes. Using curl here, but wget has a bug Bug and uses the ca-files anyway.

    sudo mv /usr/share/ca-certificates /usr/share/ca-certificates_

    Download with curl and the pinned certificate:

    curl --cacert ./torproject.pem > check.html
  • James Mitch


    # Code snippets taken from Net::SSLeay documentation and mildly modified.
    # Requires a newer version of SSLeay (tested with 1.48)
    # Needless to say, verify correct $host and $fingerprint before testing!!!
    use Net::SSLeay qw(get_https3);
    $host = "";
    $port = 443;
    $fingerprint = "C1:95:6D:C8:A7:DF:B2:A5:A5:69:34:DA:09:77:8E:3A:11:02:33:58";
    ($p, $resp, $hdrs, $server_cert) = get_https3($host, $port, '/');
    if (!defined($server_cert) || ($server_cert == 0)) {
        warn "Subject Name: undefined, Issuer  Name: undefined";
    } elsif (Net::SSLeay::X509_get_fingerprint($server_cert, "sha1") ne $fingerprint) {
        warn 'Invalid certificate fingerprint '
            .  Net::SSLeay::X509_get_fingerprint($server_cert, "sha1")
            . ' for ' . Net::SSLeay::X509_NAME_oneline(
    } else {
        print $p;

    As is outlined in the Net::SSLeay documentation, this method means verification after the HTTP transaction, and so should not be used if you want to verify you're talking to the right server before sending them data. But if all you're doing is deciding whether or not to trust what you just downloaded (which is sounds like you are from your reference #4) this is fine.

  • izx

    This is fairly easy to do with the openssl command and its client functionality.

    The following little script will take a given domain (no https prefix) and an SHA-1 fingerprint, and exit with no error (0) if the retrieved fingerprint matches, but with exit code 1 if there is no match. You can then incorporate it into your script by simply testing the last exit code $?:

    FPRINT=`echo -n | openssl s_client -connect $1:443 2>/dev/null \| openssl x509 -noout -fingerprint | cut -f2 -d'='` if [ "$2" = "$FPRINT" ]; then exit 0 else exit 1 fi

  • Related Question

    security - How do I make sure my IM client is using the right SSL certificate?
  • jrg

    Google's had fraudulent SSL certificates issued for their domains.

    enter image description here

    So, the question I have is, "How do I make sure Pidgin/Empathy trust the correct certificate?"

  • Related Answers
  • Justin Andrusk

    It really comes down to; who do you really trust? I personally would create my own self-signed certificate and would simply use that one. This is because I Know I created it and I was not relying on a third-party that could be or will be compromised. So then you would just need to trust yourself;)