生成EC Diffie-Hellman公钥和私钥对 [英] Generate EC Diffie-Hellman public and private key pair

查看:689
本文介绍了生成EC Diffie-Hellman公钥和私钥对的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要生成EC Diffie Hellman密钥对.我正在使用secp256r1命名为curve和OpenSSL.到目前为止,这就是我所拥有的:

I need to generate an EC Diffie Hellman key pair. I am using the secp256r1 named curve, and OpenSSL. This is what I have with me so far:

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曲线,但是经过一些研究,我在代码中使用了它.正确吗?

I figured out that for this function to work, i need a EVP_KEY object with the second party's public key. I have this public key in a byte array, and also its length. How do I convert it to the required type? And also I could not find the secp256r1 curve in OpenSSL, but I used the one in the code after doing some research. Is it correct?

谢谢!

推荐答案

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

The peer's public key is a point on the curve. From 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是私有标头,因此您无权访问该结构).

I believe you need to call EC_POINT_new (c_lcl.h is a private header, so you won't have access to the structure).

幸运的是,有很多功能可以操纵它们.从 EC_POINT_new(3) 文档:

Luckily, there's a lot of functions to manipulate them. From the EC_POINT_new(3) docs:

EC_POINT可以在各种外部之间进行转换 表示形式.支持的表示形式是八位字节字符串,BIGNUM 和十六进制.外部表示的格式为 由point_conversion_form描述.有关详细信息,请参见EC_GROUP_copy(3). point_conversion_form的描述.八位位组字符串存储在 缓冲区以及相关的缓冲区长度.保持在一个点 BIGNUM是通过将点转换为八位字节串和 然后将该八位位组字符串转换为BIGNUM整数.点数 十六进制格式存储在以NULL结尾的字符串中 其中每个字符都是可打印值0-9或A-F(或 a-f).

EC_POINTs can be converted to and from various external representations. Supported representations are octet strings, BIGNUMs and hexadecimal. The format of the external representation is described by the point_conversion_form. See EC_GROUP_copy(3) for a description of point_conversion_form. Octet strings are stored in a buffer along with an associated buffer length. A point held in a BIGNUM is calculated by converting the point to an octet string and then converting that octet string into a BIGNUM integer. Points in hexadecimal format are stored in a NULL terminated character string where each character is one of the printable values 0-9 or A-F (or a-f).

另请参见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);
...

您可以在椭圆曲线密码学<.

这篇关于生成EC Diffie-Hellman公钥和私钥对的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆