Hello, If I would want to use the hash of a EVP_PKEY to uniquely identify the key (regardless of whether it contains the private key or not), what would be the best way to do this? (I.e. how do I deterministically hash the public key of a EVP_PKEY?). Performance is not a major concern. The system has buffers which contain keys which are base64 encoded versions of what i2d_{RSA,DSA,EC}_PUBKEY() outputs. Internally in the applications these are made into EVP_PKEY's again by d2i_{RSA,DSA,EC_KEY}_PUBKEY() + EVP_PKEY_assign_{RSA,DSA,EC_KEY}(). How bit-by-bit identical are buffers produced by: out = NULL; switch(EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: len = i2d_RSA_PUBKEY(pkey->pkey.rsa, &out); break; case EVP_PKEY_DSA: len = i2d_DSA_PUBKEY(pkey->pkey.dsa, &out); break; case EVP_PKEY_EC: len = i2d_EC_PUBKEY(pkey->pkey.ec, &out); break; default: return SOHERR_BAD_PARAM; } .. ? I'm assuming it'll be pretty safe to hash the rsa buffer (..?) but I feel like the DSA and EC buffers are a little more sketchy (because of potential parameter issues). I browsed around in the source tree and found this: ----------------- int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { ASN1_BIT_STRING *key; key = X509_get0_pubkey_bitstr(data); if(!key) return 0; return EVP_Digest(key->data, key->length, md, len, type, NULL); } ----------------- Apart from that it uses an X509, it looks like exactly what I need, and it made me realize that the deterministic properly I'm looking for is internally called "bitstream". I tried to follow the clues from x509_get0_pubkey_bitstr(), but I quickly got confused in the ASN1 code. :) Is it safe to hash the output from i2d_*_PUBKEY? Is it super-deterministic as long as one doesn't change parameters around for DSA and EC? -- Kind Regards, Jan