X.509 Public Key Fingerprints

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

X.509 Public Key Fingerprints

Curt Sampson
I'm designing a protocol that requests certificates for specific public
keys known to the client. (I.e., the client says, "give me all of the
certs you know that are for one of these public keys," and the server
responds with those certs.)

In order to keep the request size small, I'd like to include public
key fingerprints rather than full public keys in the request. Is there
a standard way to generate a fingerprint for a public key included in
X.509 and/or PKIX certificates? Or should I just roll my own?

(We're using 2048-bit RSA keys, BTW, but the ideal solution shouldn't be
restricted to that.)

If I do roll my own, I'm thinking that the SHA-1 hash
of the public key's DER representation (as generated by
i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert))) would do the trick. There
don't appear to be any particular security issues here, since I can
verify the certs themselves after receipt to have the actual public key
I'm looking for, and be signed correctly and all of that. Any thoughts?

cjs
--
Curt Sampson         <[hidden email]>         +81 90 7737 2974

It is easier to write an incorrect program than understand a correct one.
    --Alan Perlis, Epigrams on Programming (#7)
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: X.509 Public Key Fingerprints

Philip Prindeville
Did you ever get anywhere on this?

I’m also looking for a function to generate a fingerprint (either MD5 or SHA-1 digest) over a public key DER string.

Thanks.


On Aug 15, 2012, at 2:53 AM, Curt Sampson <[hidden email]> wrote:

> I'm designing a protocol that requests certificates for specific public
> keys known to the client. (I.e., the client says, "give me all of the
> certs you know that are for one of these public keys," and the server
> responds with those certs.)
>
> In order to keep the request size small, I'd like to include public
> key fingerprints rather than full public keys in the request. Is there
> a standard way to generate a fingerprint for a public key included in
> X.509 and/or PKIX certificates? Or should I just roll my own?
>
> (We're using 2048-bit RSA keys, BTW, but the ideal solution shouldn't be
> restricted to that.)
>
> If I do roll my own, I'm thinking that the SHA-1 hash
> of the public key's DER representation (as generated by
> i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert))) would do the trick. There
> don't appear to be any particular security issues here, since I can
> verify the certs themselves after receipt to have the actual public key
> I'm looking for, and be signed correctly and all of that. Any thoughts?
>
> cjs

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: X.509 Public Key Fingerprints

Viktor Dukhovni
On Thu, Nov 20, 2014 at 12:16:41PM -0700, Philip Prindeville wrote:

> I'm also looking for a function to generate a fingerprint (either MD5 or SHA-1 digest)
> over a public key DER string.

C or command-line?  On the command-line:

    $ pkey_digest() {
        openssl x509 -in "$1" -noout -pubkey |
        openssl pkey -pubin -outform DER |
        openssl dgst -"$2" -binary |
        hexdump -ve '/1 "%02X"'; printf "\n"
      }
    $ pkey_digest cert1.pem md5
    $ pkey_digest cert2.pem sha256
    ...

In C:

    const char *digest_alg; /* = "sha1" for example */
    const EVP_MD *md;
    unsigned char mdbuf[EVP_MAX_MD_SIZE];
    unsigned char *buf;
    unsigned char *buf2;
    unsigned int len;
    unsigned int len2;
    X509 *cert;

    /* get a cert from somewhere */
    /* choose a value for digest_alg */

    if ((md = EVP_get_digestbyname(digest_alg)) == 0)
        /* error */

    len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
    buf2 = buf = (unsigned char *) OPENSSL_malloc(len);
    if (buf)
        i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf2);
    else
        /* error */
    OPENSSL_assert(buf2 - buf == len);

    if (ok = EVP_Digest(buf, len, mdbuf, &len2, md, 0))
    OPENSSL_free(buf);
    if (! ok)
        /* error */

    /* Encode len2 bytes of digest in buf to hex or whatever */

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]