需要帮助将对 EVP_PKEY_get1_EC_KEY/i2d_ECPrivateKey 和 EVP_PKEY_get1_RSA/i2d_RSAPrivateKey 的调用移植到 OpenSSL 3.0.8

问题描述 投票:0回答:1

我有使用 OpenSSL 1.1.1i 的 C/C++ 代码,并且正在切换到 OpenSSL 3.0.8。大多数事情都运行良好,但我遇到了与获取私钥的 DER 编码字节相关的问题。

下面是代码片段 - 它支持两种密钥类型:EC 和 RSA。私钥在其他地方加载并且有效。然后我确定密钥的类型,对于 EC,使用

EVP_PKEY_get1_EC_KEY
i2d_ECPrivateKey
来获取 DER 编码的字节。对于 RSA,我使用
EVP_PKEY_get1_RSA
i2d_RSAPrivateKey

这 4 个函数在 3.x.x 中已被弃用,我一生都无法弄清楚如何将这些字节放入我的

tmp
变量中 - 然后在代码的
... do stuff with tmp
部分中使用该变量。

有人知道如何在 OSSL3 中实现这一点吗?

EVP_KEY *privateKey;
int keyId;
uint_8_t *tmp;
int len;

privateKey = ... // privateKey is loaded elsewhere and is valid

keyId = EVP_PKEY_id(privateKey);

if(keyId == EVP_PKEY_EC)
{
    tmp = nullptr;
    EC_KEY *ec = EVP_PKEY_get1_EC_KEY(privateKey);
    len = i2d_ECPrivateKey(ec, &tmp);
    
    if(len > 0)
    {
        // ... do stuff with tmp

        OPENSSL_free(tmp);
    }
}
else if(keyId == EVP_PKEY_RSA)
{
    tmp = nullptr;
    RSA *rk = EVP_PKEY_get1_RSA(privateKey);
    len = i2d_RSAPrivateKey(rk, &tmp);

    if(len > 0)
    {
        // ... do stuff with tmp

        OPENSSL_free(tmp);
    }
}

我尝试了各种方法,包括调用

EVP_PKEY_get_bn_param
/
BN_bn2bin
,以及使用看起来像是使用
OSSL_ENCODER...
进行自定义编码的示例。没有运气。但是,坦率地说,我并不完全确定我正在使用这些功能做什么。

谢谢您!

openssl private-key der
1个回答
0
投票

我想我可能已经回答了我自己的问题...它涉及OSSL_ENCODER_xxx调用,重要的是在创建编码器上下文时指定

OSSL_KEYMGMT_SELECT_ALL
以及参数中的
"DER"
"type-specific"

这现在适用于 EC 私钥。我会在适当的时候测试 RSA 密钥,但我想我会发布到目前为止我发现的内容,以防有人发现它有用。

// Private key DER bytes
#if (OPENSSL_VERSION_MAJOR == 1)
    keyId = EVP_PKEY_id(privateKey);
    if(keyId == EVP_PKEY_EC)
    {
        EC_KEY *ec = EVP_PKEY_get1_EC_KEY(privateKey);
        tmp = nullptr;
        len = i2d_ECPrivateKey(ec, &tmp);
        if(len > 0)
        {
            // ... do stuff with tmp
            OPENSSL_free(tmp);
        }
    }
    else if(keyId == EVP_PKEY_RSA)
    {
        tmp = nullptr;
        RSA *rk = EVP_PKEY_get1_RSA(privateKey);
        len = i2d_RSAPrivateKey(rk, &tmp);
        if(len > 0)
        {
            // ... do stuff with tmp
            OPENSSL_free(tmp);
        }
    }
#elif (OPENSSL_VERSION_MAJOR == 3)
{  
    tmp = nullptr;
    size_t dataLen = 0;
    OSSL_ENCODER_CTX *ctx = OSSL_ENCODER_CTX_new_for_pkey(privateKey, OSSL_KEYMGMT_SELECT_ALL, "DER", "type-specific", NULL);

    if((ctx != nullptr) && (OSSL_ENCODER_to_data(ctx, &tmp, &dataLen) == 1) && (dataLen > 0))
    {
        // ... do stuff with tmp
    }

    if(tmp != nullptr)
    {
        OPENSSL_free(tmp);
    }

    OSSL_ENCODER_CTX_free(ctx);
}
#else
#error Unsupported OpenSSL version
#endif
© www.soinside.com 2019 - 2024. All rights reserved.