openssl - ECDSA:如何使用 openssl 从解压缩 x 中获取 y 坐标

标签 openssl compression point ecdsa

我试图用 ECDSA 做的是从外部 ECDSA 硬件(它实际上是一个公钥)中获取的值中获取 x“压缩”坐标和 ay“位”,然后尝试使用 OpenSSL 函数调用恢复 y 坐标(未压缩) .
我正在尝试以下代码,但它没有按我预期的那样工作(我的 xy[] 数组没有填充正确的数据)。任何人都可以帮忙吗?
我是 ECDSA 的新手,甚至是 OpenSSL 的新手,但我认为我可以执行以下操作:

EC_GROUP *curve_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1);
EC_POINT *point;
BIGNUM *x_compressed = BN_new();
int y_chooser_bit = 1;
int results = 0;
size_t returnsize = 0;
 
unsigned char x_compressed_byte_array[25] = {0x02, 0x71, 0xc0, 0x73, 0x73, 
                                             0x9b, 0xbf, 0xc2, 0x0a, 
                                             0x81, 0xcd, 0xdd, 0xf4, 
                                             0xcf, 0xca, 0xc7, 0xb5, 
                                             0xa9, 0x99, 0x61, 0x23, 
                                             0x2c, 0x5c, 0x63, 0x7a};

unsigned char xy[49];

// create a big number from the unsigned char array
BN_bin2bn(&x_compressed_byte_array[0],200,NULL); // length is in bits?

point = EC_POINT_new(curve_group);

results = EC_POINT_set_compressed_coordinates_GFp(curve_group, point, 
                                                  x_compressed,                                                               
                                                  y_chooser_bit, NULL);

returnsize = EC_POINT_point2oct(curve_group, point, 
                                POINT_CONVERSION_UNCOMPRESSED, 
                                &xy[0], 49, NULL); // 49

// clean up allocated memory
BN_free(x_compressed);
EC_POINT_free(point);
EC_GROUP_free(curve_group);

最佳答案

在这行代码中

BN_bin2bn(&x_compressed_byte_array[0],200,NULL); // length is in bits?

您应该传递 bn_compressed,即您创建的 BIGNUM,以保存转换后的结果。长度以字节为单位。
BN_bin2bn(&x_compressed_byte_array[0],sizeof(x_compressed_byte_array),x_compressed);

在设置_compressed_coordinates 后,您可以验证您刚刚创建的点是否在组中正确定位。
if (!EC_POINT_is_on_curve(curve_group,point,NULL)) return 0;

要进一步检查点坐标 (x,y),您可以将其放在代码中。
if (!EC_POINT_get_affine_coordinates_GFp(curve_group, point, x, y, NULL)) return 0;
fprintf(stdout, "\point = (x,y)\n");
fprintf(stdout, "     x = 0x");
BN_print_fp(stdout, x);
fprintf(stdout, "\n     y = 0x");
BN_print_fp(stdout, y);
fprintf(stdout, "\n");

请记住在函数的第一个/结尾处新建/释放 BIGNUM x 和 y。
BIGNUM *x, *y;
x = BN_new();
y = BN_new();

/* your code */

if(x) BN_free(x);
if(y) BN_free(y);

它应该工作。我得到的结果 xy[49] 是

0x0471C073739BBFC20A81CDDDF4CFCAC7B7A99961232C5C637C388AB06AA7E43A2B5CFE2D7F3AC2DF910D6F8D8F209CD817

关于openssl - ECDSA:如何使用 openssl 从解压缩 x 中获取 y 坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16617153/

相关文章:

php - 排名不重复

ssl - 可以在不重新颁发的情况下将 SSL 证书从 SHA1 移动到 SHA256 吗?

ssl - 从 GeoTrust 的两个证书生成 X.509 或 PEM 和私钥(RSA、PEM)

flash - SWF 闪存文件未加载 IIS 压缩

javascript - 在javascript中压缩包含音频PCM数据的blob

arrays - 当我在 Cocos2D-X 中向数组添加控制点时应用程序崩溃

c++ - Boost几何点初始化

php - 生成加密安全 token

ruby-on-rails - mac os - Gem 在下载 Rails Errno::ECONNRESET 时提供连接重置:连接由对等方重置 - SSL_connect

linux - 将多个目录压缩到一个 zip 文件中