我写了一些 C 代码女巫应该签署一个哈希。它似乎工作正常;签名,生成公钥并正确验证。但随后将签名结果用于另一个工作代码给我一个密钥验证错误(该签名用于比特币交易)
测试代码运行良好,它可以签名和验证,还使用了第三个库(比特币自己的实现),它再次运行良好。
所以我使用 OpenSSH 的方式有一个错误,但我找不到它。任何帮助表示赞赏,谢谢。
这里编译的符号生成器gcc -g -lssl -lcrypto
#include <openssl/ec.h> // for EC_GROUP_new_by_curve_name, EC_GROUP_free, EC_KEY_new, EC_KEY_set_group, EC_KEY_generate_key, EC_KEY_free
#include <openssl/ecdsa.h> // for ECDSA_do_sign, ECDSA_do_verify
#include <openssl/obj_mac.h> // for NID_secp192k1
#include <openssl/sha.h>
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
int create_signature (uint8_t * hash, int len)
{
/*
/ */ convert priv key from hexadecimal to BIGNUM
uint8_t hex[] =
{ 0x0C, 0xAE, 0xCF, 0x01, 0xD7, 0x41, 0x02, 0xA2, 0x8A, 0xED, 0x6A, 0x64,
0xDC, 0xF1, 0xCF, 0x7B, 0x0E, 0x41, 0xC4, 0xDD, 0x6C, 0x62, 0xF7, 0x0F, 0x46, 0xFE,
0xBD, 0xC3, 0x25, 0x14, 0xF0, 0xBD };*/
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,"0caecf01d74102a28aed6a64dcf1cf7b0e41c4dd6c62f70f46febdc32514f0bd");
eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
group = EC_KEY_get0_group(eckey);
EC_KEY_set_private_key(eckey, res);
int function_status = -1;
if (NULL == eckey)
{
printf ("\nFailed to create new EC Key\n");
function_status = -1;
} else {
unsigned int nSize = ECDSA_size(eckey);
uint8_t ris[nSize];
if (!ECDSA_sign(0, hash, sizeof(hash), ris, &nSize, eckey)){
printf ("\nFailed to generate EC Signature\n");
} else {
printf ("\nOK to generate EC Signature len: %d \n", nSize);
for (int i=0;i<nSize; i++) {
printf ("%02X", ris[i]);
}
{
pub_key = EC_POINT_new(group);
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("\npublic key:");
for (i=0; i<130; i++) // 1 byte 0x42, 32 bytes for X coordinate, 32 bytes for Y coordinate
{
printf("%c", *c++);
}
free(cc);
}
int verify_status = ECDSA_verify(0, hash, sizeof(hash), ris, nSize, eckey);
const int verify_success = 1;
if (verify_success != verify_status)
{
printf("\nFailed to verify EC Signature\n");
function_status = -1;
} else {
printf("\nVerifed EC Signature\n");
function_status = 1;
}
}
EC_KEY_free (eckey);
}
return function_status;
}
int main() {
uint8_t double_hash[] = { 0x5f,0xda,0x68,0x72,0x9a,0x63,0x12,0xe1,0x7e,0x64,0x1e,0x9a,0x49,0xfa,0xc2,0xa4,0xa6,0xa6,0x80,0x12,0x66,0x10,0xaf,0x57,0x3c,0xaa,0xb2,0x70,0xd2,0x32,0xf8,0x50 };
printf ("\nhash len: %d \n", sizeof(double_hash));
create_signature( double_hash, sizeof(double_hash) );
}