Как мы можем скопировать EVP_PKEY, который включает в себя ключ RSA? - PullRequest
6 голосов
/ 23 июня 2011

Я нашел функцию 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 ]

6 голосов
/ 19 августа 2011

Если вам не нужно действительно дублировать ключ, вы можете просто увеличить его счетчик ссылок, например так:

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: Как продублировать EVP_PKEY -> Как говорит @ X-Istence ниже, метод RSA_dup, предложенный в этой теме, не существует в OpenSSL (по крайней мере, до даты этого обновления).

2 голосов
/ 19 августа 2011

В 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, снова -Ваша копия:)

...