我有使用 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...
进行自定义编码的示例。没有运气。但是,坦率地说,我并不完全确定我正在使用这些功能做什么。
谢谢您!
我想我可能已经回答了我自己的问题...它涉及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