我需要生成一个 EC Diffie Hellman key 对。我正在使用 secp256r1 命名曲线和 OpenSSL。到目前为止,这就是我所拥有的:

unsigned char *ecdh(size_t *secret_len)
{
    EVP_PKEY_CTX *pctx, *kctx;
    EVP_PKEY_CTX *ctx;
    unsigned char *secret;
    EVP_PKEY *pkey = NULL, *peerkey, *params = NULL;
    /* NB: assumes pkey, peerkey have been already set up */

    /* Create the context for parameter generation */
    if(NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)))
        printf("Error in EC key generation\n");

    /* Initialise the parameter generation */
    if(1 != EVP_PKEY_paramgen_init(pctx))
        printf("Error in EC key generation\n");

    /* We're going to use the ANSI X9.62 Prime 256v1 curve */
    if(1 != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1))
        printf("Error in EC key generation\n");

    /* Create the parameter object params */
    if (!EVP_PKEY_paramgen(pctx, &params))
        printf("Error in EC key generation\n");

    /* Create the context for the key generation */
    if(NULL == (kctx = EVP_PKEY_CTX_new(params, NULL)))
        printf("Error in EC key generation\n");

    /* Generate the key */
    if(1 != EVP_PKEY_keygen_init(kctx))
        printf("Error in EC key generation\n");

    if (1 != EVP_PKEY_keygen(kctx, &pkey))
        printf("Error in EC key generation\n");

    /* Get the peer's public key, and provide the peer with our public key -
     * how this is done will be specific to your circumstances */
    peerkey = get_peerkey(pkey);

    /* Create the context for the shared secret derivation */
    if(NULL == (ctx = EVP_PKEY_CTX_new(pkey, NULL)))
        printf("Error in EC key generation\n");

    /* Initialise */
    if(1 != EVP_PKEY_derive_init(ctx))
        printf("Error in EC key generation\n");

    /* Provide the peer public key */
    if(1 != EVP_PKEY_derive_set_peer(ctx, peerkey))
        printf("Error in EC key generation\n");

    /* Determine buffer length for shared secret */
    if(1 != EVP_PKEY_derive(ctx, NULL, secret_len))
        printf("Error in EC key generation\n");

    /* Create the buffer */
    if(NULL == (secret = OPENSSL_malloc(*secret_len)))
        printf("Error in EC key generation\n");

    /* Derive the shared secret */
    if(1 != (EVP_PKEY_derive(ctx, secret, secret_len)))
        printf("Error in EC key generation\n");

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(peerkey);
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(kctx);
    EVP_PKEY_free(params);
    EVP_PKEY_CTX_free(pctx);

    /* Never use a derived secret directly. Typically it is passed
     * through some hash function to produce a key */
    return secret;
}

我发现要使这个函数起作用,我需要一个带有第二方公钥的 EVP_KEY 对象。我在一个字节数组中有这个公钥,还有它的长度。如何将其转换为所需的类型?而且我在 OpenSSL 中找不到 secp256r1 曲线,但我在做了一些研究后在代码中使用了该曲线。这是正确的吗?

谢谢 !

最佳答案

对等方的公钥是曲线上的一个点。从 crypto\ec\ec_lcl.h :

struct ec_key_st {
    int version;

    EC_GROUP *group;

    EC_POINT *pub_key;
    BIGNUM   *priv_key;

    unsigned int enc_flag;
    point_conversion_form_t conv_form;

    int     references;
    int flags;

    EC_EXTRA_DATA *method_data;
} /* EC_KEY */;

我相信您需要调用 EC_POINT_new ( c_lcl.h 是一个私有(private) header ,因此您将无法访问该结构)。

幸运的是,有很多函数可以操作它们。来自 EC_POINT_new(3) 文档:



另见 EC_POINT_set_affine_coordinates_GFpEC_POINT_set_affine_coordinates_GF2mEC_KEY_set_public_key :
$ grep -R EC_KEY_set_public_key *
crypto/ec/ec.h:int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
...

您可以在 OpenSSL wiki 的 Elliptic Curve Cryptography 上查看如何设置点的示例。

关于c - 生成 EC Diffie-Hellman 公私钥对,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24919173/

10-10 06:02