我需要生成 EC Diffie Hellman 密钥对。我正在使用名为 curve 的 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, ¶ms))
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 曲线,但我在做了一些研究后在代码中使用了该曲线。这是对的吗?
Thanks !
对等点的公钥是曲线上的一个点。从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 */;
I believe你需要打电话EC_POINT_new
(c_lcl.h
是私有标头,因此您无权访问该结构)。
幸运的是,有很多函数可以操纵它们。来自EC_POINT_new(3) http://www.openssl.org/docs/crypto/EC_POINT_new.html docs:
EC_POINT 可以与各种外部进行转换
交涉。支持的表示形式为八位字节字符串、BIGNUM
和十六进制。外部表示的格式为
由point_conversion_form描述。请参阅 EC_GROUP_copy(3) 了解
point_conversion_form 的描述。八位字节字符串存储在
缓冲区以及相关的缓冲区长度。一个点保存在
BIGNUM 是通过将点转换为八位字节字符串来计算的
然后将该八位字节字符串转换为 BIGNUM 整数。点在
十六进制格式存储在以 NULL 结尾的字符串中
其中每个字符是可打印值 0-9 或 A-F 之一(或
a-f)。
另请参阅EC_POINT_set_affine_coordinates_GFp
, EC_POINT_set_affine_coordinates_GF2m
and EC_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 上查看如何设置该点的示例:椭圆曲线密码学 http://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)