X25519 不能使用EC_KEY接口
X25519和其他的ECC不同,在openssl,没有实现EC_KEY 相关接口,所以
EC_KEY_set_private_key
EC_KEY_new_by_curve_name
EC_KEY_get0_group
这些接口对 X25519是不通的。
openssl 中,X25519被实现为一个独立的算法,并且不是建立在EC库之上,即在EVP_PKEY中的某个地方没有包含X25519的EC_KEY。同样,您将永远无法从X25519 nid创建EC_KEY,因为这毫无意义:EC库不知道如何处理曲线25519,因此无法为其创建EC_KEY。
X25519 Openssl接口实现源码
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/ossl_typ.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/obj_mac.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <stdio.h>
unsigned char pub_data [1000] ={
0x6b,0xfa,0x30,0x2f,0x99,0x73,0xd1,0xe6,0xec,0xa2,0x42,0xdd,0x65,0xe4,0x57,0x38,0xf8,0x53,0x9e,0xfe,0x75,0xeb,0x42,0x4e,0x91,0xa8,0x48,0x27,0x59,0xdc,0xf7,0x32
};
unsigned char priv_data [1000] ={
0x67, 0xc6, 0x69, 0x73, 0x51, 0xff, 0x4a, 0xec, 0x29, 0xcd, 0xba, 0xab, 0xf2, 0xfb, 0xe3, 0x46, 0x7c, 0xc2, 0x54, 0xf8, 0x1b, 0xe8, 0xe7, 0x8d, 0x76, 0x5a, 0x2e, 0x63, 0x33, 0x9f, 0xc9, 0x9a
};
void dump_hex(const char *str, unsigned char *hex_data, int len) {
int i = 0;
printf("hex len %d\n",len);
printf("%s", str);
for (i = 0; i < len; i++) {
if (i % 16 == 0) printf("\n");
printf("0x%02x, ", hex_data[i]);
}
printf("\n");
}
int main(int argc, const char *argv[])
{
unsigned char out[100] = {0};
EVP_PKEY_CTX *ctx;
EVP_PKEY_CTX *dctx;
EVP_PKEY *pkey= NULL;
EVP_PKEY *pub= NULL;
pub = EVP_PKEY_new();
ctx = EVP_PKEY_CTX_new_id(NID_X25519, NULL);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY_keygen(ctx, &pkey);
dctx = EVP_PKEY_CTX_new(pkey,0);
//初始化密钥交换
int er=EVP_PKEY_derive_init(dctx);
if (er != 1)
{
EVP_PKEY_CTX_free(dctx);
ERR_print_errors_fp(stderr);
return 0;
}
EVP_PKEY_copy_parameters(pub, pkey);
EVP_PKEY_set1_tls_encodedpoint(pub, pub_data, 32);
#if 1
unsigned char tmp[1000] = {0};
size_t tmp_len = 1000;
// EVP_PKEY_get_raw_private_key(pkey, tmp, &tmp_len);
// dump_hex("pri",tmp, tmp_len);
tmp_len = 1000;
EVP_PKEY_get_raw_public_key(pkey, tmp ,&tmp_len);
dump_hex("pub",tmp, tmp_len);
tmp_len = 1000;
EVP_PKEY_get_raw_public_key(pub, tmp ,&tmp_len);
dump_hex("cli pub",tmp, tmp_len);
#endif
//设定对方公钥 bG 和私钥a
int re=EVP_PKEY_derive_set_peer(dctx, pub);
if (re != 1)
{
EVP_PKEY_CTX_free(dctx);
ERR_print_errors_fp(stderr);
return 0;
}
//开始计算
size_t outsize = 1024;
re=EVP_PKEY_derive(dctx, out, &outsize);
if (re != 1)
{
EVP_PKEY_CTX_free(dctx);
ERR_print_errors_fp(stderr);
return 0;
}
dump_hex("share key:",out,outsize);
EVP_PKEY_CTX_free(dctx);
EVP_PKEY_CTX_free(ctx);
return 0;
}