使用 ECC 生成 private/public 对密钥:椭圆曲线
Generate private/public pair key using ECC : elliptic curves
我正在研究小 ECC 加密问题。
目标是用C或bash写一个程序,它将输入一个由128个字符组成的十六进制散列
(Example: 8A9A35145C4EA5260DF9972C804FE2D3F9F3D7A2AC01A6BEB21C82BB30957B3952273AC9166B90C1207347A925780F84A1D2359E7AA05201C674D2B9746FCA07)
并且将从 input hash
生成私钥和 椭圆曲线 类型的 public 密钥,并显示生成的密钥对。
谁能帮我解释一下这个问题。我不明白为什么我们需要散列(或任何字符串)来生成一对密钥,正如我在许多在线解决方案中发现的那样 this one 不需要提供散列。也许这是一个parphase?也许是曲线键或类似的东西。
我认为我们只需要为私钥做这样的事情:
openssl ecparam -genkey -noout -out myprivatekey.pem
对于 public 密钥生成:
openssl -ec -in myprivatekey.pem -pubout -out mypublickey.pem
问题是:为什么我们需要输入一个由 128 组成的散列来生成我们的密钥对?出于安全原因,它是密码吗? openssl 是如何成功的?
如果您有某种输入二进制值需要将其转换为密钥,则可以使用散列。
您可以使用哈希作为私钥的输入。要转换它,您应该先将其转换为数字,然后对其进行模 n
计算,其中 n
是 ECC 域参数的顺序。结果值可以称为 s
然后你可以通过执行 s * G
计算出 public 键,即与基点的点乘。
OpenSSL 不是低级加密库,因此您必须对其进行编程,可能使用 OpenSSL API 和它附带的 BN(大数)库。 并不棘手,但如果您仍在谈论 128 个字符而不是 64 个字节,那么您可能需要学习很多东西。
实际上这是我自己的代码,您可以改进它并编辑下面的解决方案:
// 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;
}
我正在研究小 ECC 加密问题。
目标是用C或bash写一个程序,它将输入一个由128个字符组成的十六进制散列
(Example: 8A9A35145C4EA5260DF9972C804FE2D3F9F3D7A2AC01A6BEB21C82BB30957B3952273AC9166B90C1207347A925780F84A1D2359E7AA05201C674D2B9746FCA07)
并且将从 input hash
生成私钥和 椭圆曲线 类型的 public 密钥,并显示生成的密钥对。
谁能帮我解释一下这个问题。我不明白为什么我们需要散列(或任何字符串)来生成一对密钥,正如我在许多在线解决方案中发现的那样 this one 不需要提供散列。也许这是一个parphase?也许是曲线键或类似的东西。
我认为我们只需要为私钥做这样的事情:
openssl ecparam -genkey -noout -out myprivatekey.pem
对于 public 密钥生成:
openssl -ec -in myprivatekey.pem -pubout -out mypublickey.pem
问题是:为什么我们需要输入一个由 128 组成的散列来生成我们的密钥对?出于安全原因,它是密码吗? openssl 是如何成功的?
如果您有某种输入二进制值需要将其转换为密钥,则可以使用散列。
您可以使用哈希作为私钥的输入。要转换它,您应该先将其转换为数字,然后对其进行模 n
计算,其中 n
是 ECC 域参数的顺序。结果值可以称为 s
然后你可以通过执行 s * G
计算出 public 键,即与基点的点乘。
OpenSSL 不是低级加密库,因此您必须对其进行编程,可能使用 OpenSSL API 和它附带的 BN(大数)库。 并不棘手,但如果您仍在谈论 128 个字符而不是 64 个字节,那么您可能需要学习很多东西。
实际上这是我自己的代码,您可以改进它并编辑下面的解决方案:
// 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;
}