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

时间:2011-06-23 04:47:27

标签: c openssl x509 private-key

我找到了可以复制EVP_PKEY_copy_parameters的函数EVP_PKEY。 但有关此功能的一些文档称它只能用于DSA / ECC算法。 官方文档(来自openssl.org)未提及该函数是否可用于RSA EVP_PKEY。

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

EVP_PKEY_assign_RSA(RSAPrivateKey_dup(EVP_PKEY_get1_RSA(pkey)));

你有什么建议吗?

2 个答案:

答案 0 :(得分:6)

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

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;
}

参考:Re: How to duplicate an EVP_PKEY - >正如@ X-Istence所说,OpenSSL中不存在此参考线程中建议的RSA_dup方法(至少在此更新之前)。

答案 1 :(得分:2)

在OpenSSL 1.0.0d中,EVP_PKEY_copy_parameters应该可以正常工作。但是,从实施情况来看,它似乎只是复制了公共参数:

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_RSAPrivateKey你的RSA密钥,然后再d2i_RSAPrivateKey它 - 你的副本是:)