【问题标题】:How can we copy an EVP_PKEY which includes RSA key?我们如何复制包含 RSA 密钥的 EVP_PKEY?
【发布时间】:2011-09-20 22:09:27
【问题描述】:

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

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

EVP_PKEY_assign_RSA(RSAPrivateKey_dup(EVP_PKEY_get1_RSA(pkey)));

你有什么建议吗?

【问题讨论】:

    标签: c openssl x509 private-key


    【解决方案1】:

    如果您真的不需要复制键,则可以增加其引用计数,如下所示:

    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 下面所说,此参考线程中建议的RSA_dup 方法在 OpenSSL 中不存在(至少在此更新日期之前) )。

    【讨论】:

    • RSA_dup 在 OpenSSL 源代码中的任何地方都不存在。特别是在同一个电子邮件线程中,同一个发帖人的后续行动同样如此:mail-archive.com/openssl-users@openssl.org/msg17617.html
    • dst_pkey 泄漏
    • @Orient 你是对的。谢谢!我对dst_pkey 进行了虚假/不必要的分配。传递的参数必须引用预先分配的 pkey。
    【解决方案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 它 - 这是你的副本 :)

    【讨论】:

    • 使用 PEM_write_PrivateKey/PEM_read_PrivateKey 代替需要您知道底层类型是什么的 i2d/d2i 方法。这样 RSA、DH、EC 和 DSA 私钥都可以在不明确知道底层类型的情况下复制。
    • 我会将 i2d/d2i 用于其他目的。这个答案真的为我节省了几天和几天的工作......现在,我会适应明天的截止日期......非常感谢,伙计
    猜你喜欢
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 2013-10-30
    • 2019-02-15
    相关资源
    最近更新 更多