使用ECC生成私钥/公钥对:椭圆曲线

时间:2018-08-19 21:55:10

标签: cryptography elliptic-curve

我正在研究小ECC加密问题。

目标是用C或bash编写程序,将以128个十六进制字符组成的哈希作为输入
(Example: 8A9A35145C4EA5260DF9972C804FE2D3F9F3D7A2AC01A6BEB21C82BB30957B3952273AC9166B90C1207347A925780F84A1D2359E7AA05201C674D2B9746FCA07) 并从input hash生成椭圆曲线类型的私钥和公钥,并显示生成的密钥对。

有人可以为我澄清这个问题吗?我不明白为什么我们需要哈希(或任何字符串)来生成配对密钥,正如我在许多this one这样的在线解决方案中发现的那样,无需提供哈希。也许是阶段性的?也许是曲线键或类似的东西。

我认为我们需要对私钥执行以下操作:
openssl ecparam -genkey -noout -out myprivatekey.pem 对于公共密钥生成: openssl -ec -in myprivatekey.pem -pubout -out mypublickey.pem

问题是:为什么我们需要输入一个由128组成的哈希来生成我们的配对密钥?出于安全原因,这是密码吗? openssl如何制作花招?

2 个答案:

答案 0 :(得分:1)

如果您需要某种输入二进制值并将其转换为键,则可以使用哈希。

您可以将散列用作私钥的输入。要对其进行转换,您应该首先将其转换为数字,然后对其进行模n的计算,其中n是ECC域参数的顺序。可以将结果值称为s,然后可以通过执行s * G(即与基点的乘积)来计算出公钥。

OpenSSL不是低级别的加密库,因此您必须对其进行编程,可能使用其随附的OpenSSL API和BN(大数字)库。 并不是那么棘手,但是如果您仍在谈论128个字符而不是64个字节,那么您可能需要学习很多东西。

答案 1 :(得分:0)

实际上这是我自己的代码,您可以对其进行改进并编辑以下解决方案:

// 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;

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

     res = start;
     BN_hex2bn(&res,"8A9A35145C4EA5260DF9972C804FE2D3F9F3D7A2AC01A6BEB21C82BB30957B3952273AC9166B90C1207347A925780F84A1D2359E7AA05201C674D2B9746FCA07");
     eckey = EC_KEY_new_by_curve_name(NID_secp256k1);

     group = EC_KEY_get0_group(eckey);
     pub_key = EC_POINT_new(group);


    printf("private key : "); BN_print_fp(stdout, res); printf("\n");
    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");

     EC_KEY_set_public_key(eckey, pub_key);

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

     char *c=cc;

     int i;

     printf("public key : ");
     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;
}