C 我们如何复制包含RSA密钥的EVP_PKEY?

C 我们如何复制包含RSA密钥的EVP_PKEY?,c,openssl,x509,private-key,C,Openssl,X509,Private Key,我找到了函数EVP\u PKEY\u copy\u parameters,它可以复制EVP\u PKEY。 但是一些关于这个函数的文档说它只能用于DSA/ECC算法。 官方文档(来自)未提及该功能是否可用于RSA EVP_PKEYs EVP_PKEY(包含RSA密钥)的另一个实现可能是: EVP_PKEY_assign_RSA(RSAPrivateKey_dup(EVP_PKEY_get1_RSA(pkey))); 你有什么建议吗?如果你不是真的需要复制密钥,你可以增加它的引用计数,如下所示:

我找到了函数
EVP\u PKEY\u copy\u parameters
,它可以复制
EVP\u PKEY
。 但是一些关于这个函数的文档说它只能用于DSA/ECC算法。 官方文档(来自)未提及该功能是否可用于RSA EVP_PKEYs

EVP_PKEY(包含RSA密钥)的另一个实现可能是:

EVP_PKEY_assign_RSA(RSAPrivateKey_dup(EVP_PKEY_get1_RSA(pkey)));

你有什么建议吗?

如果你不是真的需要复制密钥,你可以增加它的引用计数,如下所示:

CRYPTO_add(&your_evp_pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
否则,与您建议的类似(几乎相同)方法如下:

int pkey_rsa_dup(EVP_PKEY *dst_pkey, EVP_PKEY *src_key) {
    // Validate underlying key type - Only allow a RSA key
    if (src_key->type != EVP_PKEY_RSA)
        return -1;

    RSA *rsa = EVP_PKEY_get1_RSA(src_key); // Get the underlying RSA key
    RSA *dup_rsa = RSAPrivateKey_dup(rsa); // Duplicate the RSA key
    RSA_free(rsa); // Decrement reference count

    EVP_PKEY_set1_RSA(dst_pkey, dup_rsa); // Set the underlying RSA key in dst_pkey
    // EVP_PKEY_set1_RSA also adjusts the other members in dst_pkey

    return 0;
}

参考:->正如@X-Istence在下面所说的,在OpenSSL中不存在此参考线程中建议的
RSA\u dup
方法(至少在此更新日期之前)。

在OpenSSL 1.0.0d中,
EVP\u PKEY\u copy\u参数
应该可以工作。但是,从实现来看,它似乎只是复制了公共参数:

static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
    RSA_PKEY_CTX *dctx, *sctx;
    if (!pkey_rsa_init(dst))
        return 0;
    sctx = src->data;
    dctx = dst->data;
    dctx->nbits = sctx->nbits;
    if (sctx->pub_exp) {
        dctx->pub_exp = BN_dup(sctx->pub_exp);
        if (!dctx->pub_exp)
            return 0;
    }
    dctx->pad_mode = sctx->pad_mode;
    dctx->md = sctx->md;
    return 1;
}

除了jweyrich的解决方案之外,另一个简单的方法是首先
i2d\u RSAPrivateKey
您的RSA密钥,然后
d2i\u RSAPrivateKey
再次使用它-这是您的副本:)

RSA\u-dup在OpenSSL源代码中的任何地方都不存在。具体地说,在同一封邮件中,同一张海报的后续内容同样如此:
dst_pkey
leaks@Orient你说得对。谢谢我对
dst\u pkey
进行了虚假/不必要的分配。传递的参数必须引用预分配的pkey。请改用PEM_write_PrivateKey/PEM_read_PrivateKey,而不是要求您了解底层类型的i2d/d2i方法。这样,RSA、DH、EC和DSA私钥都被复制,而不需要明确知道底层类型。这个答案真的帮我省了好几天的工作。。。现在,我将赶上明天的最后期限。。。。非常感谢,伙计