Siler
Siler

Reputation: 9484

Comparing two public keys with OpenSSL API

I'm looking for a way to compare two public keys using the OpenSSL API in C++. Of course, the most obvious way would be to serialize both keys into some format like PEM or DER, and then just compare the two serialized buffers.

But I'm wondering if there is a more efficient way to compare the two keys that directly uses the OpenSSL key structures in memory. Obviously, doing this would probably require different logic depending on what algorithm was used to generate the public key (along with its private counterpart.)

So, to start out with something simple, suppose we only initially care about comparing RSA keys. Since the public component of an RSA key is the modulus n and the public exponent e, it seems we could just try to get those two numbers from each key and just compare them directly. If they are equal, we can say the two public keys are equal.

The OpenSSL API provides a function to get these values, RSA_get0_key, which returns pointers to the internal BIGNUM objects n, e, and d, stored in the RSA struct. We could then use BN_cmp to compare these objects directly. So the C++ code would be something like:

bool compare_pubkeys(const EVP_PKEY* k1, const EVP_PKEY* k2)
{
    // make sure both keys are the same type
    const int tp1 = EVP_PKEY_type(k1->type);
    const int tp2 = EVP_PKEY_type(k2->type);
    if (tp1 != tp2) return false;

    if (tp1 == EVP_PKEY_RSA) {
        RSA* rsa1 = EVP_PKEY_get1_RSA(k1);
        RSA* rsa2 = EVP_PKEY_get1_RSA(k2);

        const BIGNUM* n1;
        const BIGNUM* e1;
        const BIGNUM* n2;
        const BIGNUM* e2;
        RSA_get0_key(rsa1, &n1, &e1, nullptr);
        RSA_get0_key(rsa2, &n2, &e2, nullptr);
        const bool result = BN_cmp(n1, n2) == 0 && BN_cmp(e1, e2) == 0;

        RSA_free(rsa1);
        RSA_free(rsa2);
        return result;
    }
    else { /* handle non-RSA keys later */ }

    return false;
}

My question: does this approach make sense? I'm not by any means an expert in cryptography and I have an extremely basic understanding of how RSA keys work, so I don't know if there is something wrong with my approach. My understanding is that given two RSA key pairs, comparing each n and e would be conceptually equivalent to checking if the two public keys were the same - but again, I'm not an expert so I am unsure if this is correct.

So, is my approach here correct?

Upvotes: 1

Views: 1995

Answers (1)

arved
arved

Reputation: 4576

There is a function called EVP_PKEY_cmp, that seems to do, what you are trying to do.

see https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_cmp.html

Upvotes: 5

Related Questions