验证OpenSSL中的RSA公钥? [英] Verify a RSA public key in OpenSSL?

查看:278
本文介绍了验证OpenSSL中的RSA公钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个仅包含RSA密钥公开部分的EVP_PKEY.我从DER编码的SubjectPublicKeyInfo结构中提取了公共部分.这就是我现在拥有的:

I have an EVP_PKEY with only the public part of a RSA key. I extracted the public part from a SubjectPublicKeyInfo structure in DER encoding. This is what I have now:

unsigned char publicKey[] = {0x30, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, ...}
size_t publicKeyLength = 92;
unsigned char* publicKeyCopy = new unsigned char[publicKeyLength];
memcpy(publicKeyCopy, publicKey, publicKeyLength);

RSA *rsa;
rsa = d2i_RSA_PUBKEY(NULL, (unsigned char const **) &pubKey, pubKeyLen);
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, rsa);

我知道您可以使用 RSA_check_key来验证RSA私钥但是文档说"它不适用于仅填充了模数和公共指数元素的RSA公钥".

I know that you can use RSA_check_key to verify a RSA private key but the docs say that "It does not work on RSA public keys that have only the modulus and public exponent elements populated".

那么,可以在没有私有部分的情况下验证密钥吗?因为如您所见,我只有 EVP_PKEY的公共部分.我不知道,这有可能吗?您会在EVP_PKEY的公开部分中验证什么?

So, is it possible to verify a key without the private part? Because as you can see I have only the public part of the EVP_PKEY. I wonder, is this even possible? What would you verify in a public part of an EVP_PKEY?

您可以看到此问题的答案以编程方式验证X509证书和私钥匹配,但此处的完整密钥已通过验证(私钥和公钥).

You can see the answer for this question Programmatically verify a X509 certificate and private key match but there the full key is validated (private and public parts).

当心 此问题中发布的原始代码有错误.这是因为内部d2i_RSA_PUBKEY使用d2i_PUBKEY,而d2i_PUBKEY使用d2i_X509_PUBKEY(在 x_pubkey.c 中).如果您阅读d2i_X509的文档,您将看到下一个警告:必须使用临时变量.一个常见的错误是试图直接使用缓冲区..." . 因此,更正后的代码将必须使用publicKeyCopy的临时副本,使用后,您可以安全地删除publicKeyCopy:

Beware The original code posted in this question has a BUG. This is because internally d2i_RSA_PUBKEY uses d2i_PUBKEY and d2i_PUBKEY uses d2i_X509_PUBKEY (in x_pubkey.c). If you read the documentation for d2i_X509 you will see the next "WARNING: The use of temporary variable is mandatory. A common mistake is to attempt to use a buffer directly...". So the corrected code will have to use a temporary copy of publicKeyCopy and after the use you could safely delete publicKeyCopy:

推荐答案

借助@jww在此答案中 https://stackoverflow.com/a/29885771/2692914 .我想出了这个解决方案,希望可以:

With the help of @jww in this answer https://stackoverflow.com/a/29885771/2692914. I came up with this solution, I hope it is ok:

bool isValidPublicKeyOnly(EVP_PKEY *pkey) {
    //EVP_PKEY_get_type from https://stackoverflow.com/a/29885771/2692914
    int type = EVP_PKEY_get_type(pkey); //checks nullptr
    if (type != EVP_PKEY_RSA && type != EVP_PKEY_RSA2) {
        //not RSA
        return false;
    }

    RSA *rsa = EVP_PKEY_get1_RSA(pkey);
    if (!rsa) {
        return false;
    }

    bool isValid = isValidRSAPublicKeyOnly(rsa);
    RSA_free(rsa);
    return isValid;
}

bool isValidRSAPublicKeyOnly(RSA *rsa) {
    //from rsa_ameth.c do_rsa_print : has a private key
    //from rsa_chk.c RSA_check_key : doesn't have n (modulus) and e (public exponent)
    if (!rsa || rsa->d || !rsa->n || !rsa->e) {
        return false;
    }
    //from http://rt.openssl.org/Ticket/Display.html?user=guest&pass=guest&id=1454
    //doesnt have a valid public exponent
    return BN_is_odd(rsa->e) && !BN_is_one(rsa->e);
}

这篇关于验证OpenSSL中的RSA公钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆