Cryptography 如何从OpenSSL中的ECDSA私钥获取公钥?

Cryptography 如何从OpenSSL中的ECDSA私钥获取公钥?,cryptography,openssl,public-key-encryption,elliptic-curve,Cryptography,Openssl,Public Key Encryption,Elliptic Curve,我提供这个示例应用程序来说明我的问题 #包括 #包括 #包括 #包括 int main() { EC_KEY*pkey=NULL; EC_点*pub_键=NULL; const EC_GROUP*GROUP=NULL; BIGNUM启动; BIGNUM*res; BN_CTX*CTX; BN_init(&start); ctx=BN_ctx_new(); res=&start; BN_hex2bn(&res,“3D79F601620A6D05DB7FED883AB8BCD08A9101B166B

我提供这个示例应用程序来说明我的问题

#包括
#包括
#包括
#包括
int main()
{
EC_KEY*pkey=NULL;
EC_点*pub_键=NULL;
const EC_GROUP*GROUP=NULL;
BIGNUM启动;
BIGNUM*res;
BN_CTX*CTX;
BN_init(&start);
ctx=BN_ctx_new();
res=&start;
BN_hex2bn(&res,“3D79F601620A6D05DB7FED883AB8BCD08A9101B166BC0166869DA5FC08D936E”);
pkey=EC_KEY_new_by_curve_name(NID_secp256k1);
组=EC_KEY_get0_组(pkey);
pub_key=EC_POINT_new(组);
EC_KEY_set_private_KEY(pkey,res);
assert(EC_POINT_bn2 POINT(group,res,pub_key,ctx));//此处为Null
EC_KEY_set_public_KEY(pkey,pub_KEY);
返回0;
}
我试图做的是显示私钥中的公钥(应该是椭圆私钥)。 直到遇到类似的问题,我才知道怎么做

在这里,我告诉自己如何获取公钥,如何使用EC_POINT_bn2 POINT而不是hex2point,根据OpenSSL源代码,hex2point在内部执行BN_hex2bn

那么,为什么EC_POINT_bn2 POINT返回NULL?我正在认真考虑重新编译OpenSSL,并使用一些调试例程来找出它失败的原因。

ECDSA私钥d(一个整数)和公钥Q(一个点)由Q=dG计算,其中G是一个非秘密域参数。详细描述了ECDSA

OpenSSL用于生成密钥对。它所做的是随机生成一个私钥,然后执行Q=dG乘法来计算公钥:

/* pub_key is a new uninitialized `EC_POINT*`.  priv_key is a `BIGNUM*`. */
if (!EC_POINT_mul(ecdsa->group, pub_key, priv_key, NULL, NULL, ctx)) goto err;
所以你可以做同样的事情。如果我有私钥,我会将其设置为
EC_-key
ECDSA
结构中的私钥。然后我会在上面配置域参数。最后,我将执行
EC\u POINT\u mul
以获取公钥点。

工作示例:

// using figures on: https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses
// gcc -Wall ecdsapubkey.c -o ecdsapubkey -lcrypto
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>

int main()
{
     EC_KEY *eckey = NULL;
     EC_POINT *pub_key = NULL;
     const EC_GROUP *group = NULL;
     BIGNUM start;
     BIGNUM *res;
     BN_CTX *ctx;

     BN_init(&start);
     ctx = BN_CTX_new(); // ctx is an optional buffer to save time from allocating and deallocating memory whenever required

     res = &start;
//     BN_hex2bn(&res,"3D79F601620A6D05DB7FED883AB8BCD08A9101B166BC60166869DA5FC08D936E");
     BN_hex2bn(&res,"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
     eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
     group = EC_KEY_get0_group(eckey);
     pub_key = EC_POINT_new(group);

     EC_KEY_set_private_key(eckey, res);

     /* pub_key is a new uninitialized `EC_POINT*`.  priv_key res is a `BIGNUM*`. */
     if (!EC_POINT_mul(group, pub_key, res, NULL, NULL, ctx))
       printf("Error at EC_POINT_mul.\n");

//     assert(EC_POINT_bn2point(group, &res, pub_key, ctx)); // Null here

     EC_KEY_set_public_key(eckey, pub_key);

     char *cc = EC_POINT_point2hex(group, pub_key, 4, ctx);

     char *c=cc;

     int i;

     for (i=0; i<130; i++) // 1 byte 0x42, 32 bytes for X coordinate, 32 bytes for Y coordinate
     {
       printf("%c", *c++);
     }

     printf("\n");

     BN_CTX_free(ctx);

     free(cc);

     return 0;
}
//使用以下图形:https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses
//gcc-Wall ecdsapubkey.c-o ecdsapubkey-lcrypto
#包括
#包括
#包括
#包括
#包括
int main()
{
EC_KEY*eckey=NULL;
EC_点*pub_键=NULL;
const EC_GROUP*GROUP=NULL;
BIGNUM启动;
BIGNUM*res;
BN_CTX*CTX;
BN_init(&start);
ctx=BN_ctx_new();//ctx是一个可选的缓冲区,可以节省在需要时分配和释放内存的时间
res=&start;
//BN_hex2bn(&res,“3D79F601620A6D05DB7FED883AB8BCD08A9101B166BC0166869DA5FC08D936E”);
BN_hex2bn(&res),“18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725”);
eckey=eckey新曲线名称(NID secp256k1);
组=eckey组(eckey);
pub_key=EC_POINT_new(组);
EC_密钥_设置_私钥(eckey,res);
/*pub_key是一个新的未初始化的'EC_POINT*`。priv_key res是一个'BIGNUM*`*/
if(!EC_POINT_mul(组、发布键、res、NULL、NULL、ctx))
printf(“EC点错误。\n”);
//assert(EC_POINT_bn2 POINT(group,&res,pub_key,ctx));//此处为Null
EC_KEY_set_public_KEY(eckey,pub_KEY);
char*cc=EC_POINT_point2hex(组,发布键,4,ctx);
char*c=cc;
int i;

对于(i=0;iWell,如果你能从私钥中提取公钥,那就违背了RSA的本质……我发现一些文章说私钥留下了一些生成发布密钥的线索,但它不是用英语写的。因此,你可以找到私钥的格式,这可能会有所帮助。ECDSA私钥
d
(一个整数)和公钥
Q
(一个点)由
Q=dG
计算,其中G是一个非秘密域参数。另请参见:是的,我获得了它。我需要与基生成器G进行EC乘法。