我正在寻找一种使用C ++中的OpenSSL API比较两个公用密钥的方法。当然,最明显的方法是将两个密钥序列化为PEM或DER等格式,然后比较两个序列化的缓冲区。
但是我想知道是否有更有效的方法来比较直接在内存中使用OpenSSL密钥结构的两个密钥。显然,根据用于生成公钥的算法(以及私钥的对应算法),这样做可能需要不同的逻辑。
因此,以简单的内容开始,假设我们最初只关心比较RSA密钥。由于public component of an RSA key是模数routeDocument
和公共指数isVisible
,因此我们似乎可以尝试从每个键中获取这两个数字并直接进行比较。如果它们相等,则可以说两个公钥相等。
OpenSSL API提供了获取这些值RSA_get0_key
的函数,该函数返回指向内部n
对象e
,BIGNUM
和n
的指针,存储在e
结构中。然后,我们可以使用d
直接比较这些对象。因此,C ++代码类似于:
RSA
我的问题:这种方法有意义吗?我绝对不是密码学专家,并且我对RSA密钥的工作原理有非常基本的了解,所以我不知道我的方法是否有问题。我的理解是,在给定两个RSA密钥对的情况下,比较每个BN_cmp
和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;
}
在概念上等同于检查两个公钥是否相同-但同样,我不是专家,所以我不确定这是否正确。
那么,我的方法正确吗?
答案 0 :(得分:3)
有一个名为EVP_PKEY_cmp的函数,该函数似乎可以执行您要执行的操作。
请参阅https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_cmp.html