【发布时间】:2018-10-02 03:11:50
【问题描述】:
我正在寻找一种在 C++ 中使用 OpenSSL API 比较两个公钥的方法。当然,最明显的方法是将两个密钥序列化为某种格式,如 PEM 或 DER,然后只比较两个序列化的缓冲区。
但我想知道是否有更有效的方法来比较直接使用内存中 OpenSSL 密钥结构的两个密钥。显然,这样做可能需要不同的逻辑,具体取决于用于生成公钥(以及对应的私钥)的算法。
所以,从简单的开始,假设我们最初只关心比较 RSA 密钥。由于public component of an RSA key 是模数n 和公共指数e,看来我们可以尝试从每个键中获取这两个数字并直接比较它们。如果它们相等,我们可以说两个公钥相等。
OpenSSL API 提供了一个函数来获取这些值,RSA_get0_key,它返回指向内部BIGNUM 对象n、e 和d 的指针,这些对象存储在RSA 结构中。然后我们可以使用BN_cmp 直接比较这些对象。所以 C++ 代码会是这样的:
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;
}
我的问题:这种方法有意义吗?我绝不是密码学专家,而且我对 RSA 密钥的工作原理有非常基本的了解,所以我不知道我的方法是否有问题。我的理解是,给定两个 RSA 密钥对,比较每个 n 和 e 在概念上等同于检查两个公钥是否相同 - 但同样,我不是专家,所以我不确定这是否是正确。
那么,我的方法正确吗?
【问题讨论】:
-
为什么要关心效率?您需要每秒比较数千个密钥吗?
-
如果你问
(n1 == n2) && (e1 == e2)是否暗示k1 == k2(反之亦然),那么我认为Cryptography SE是一个更好的地方。如果这不是您要问的,那么您能更具体一点吗?