在OpenSSL中使用ECDSA签名消息
在以编程方式在OpenSSL中使用ECDSA时,如何设置用于签名消息的私钥? 我有以下代码:
static int create_signature(unsigned char* hash) { EC_KEY *eckey=NULL; EC_GROUP *ecgroup=NULL; EVP_PKEY *evpkey=NULL; unsigned char *signature=NULL; point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; int signature_size, block_size; unsigned char * block=NULL; ecgroup = get_ec_group_192(); EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE); EC_GROUP_set_point_conversion_form(ecgroup, form); eckey=EC_KEY_new(); EC_KEY_set_group(eckey,ecgroup); EC_KEY_generate_key(eckey); evpkey=EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(evpkey,eckey); signature=OPENSSL_malloc(EVP_PKEY_size(evpkey)); ECDSA_sign(0, hash, sizeof(hash), signature, &signature_size, eckey); printf("%s", signature); return 0; }
函数get_ec_group_192()
是通过运行openssl ecparam -C -name secp192k1 -genkey
创建的,该函数还生成一些EC PARAMETERS
和EC PRIVATE KEY
。
我想要做的是用我的私钥加密hash
包含的消息,这样只有公钥才能解密它。 这可能与上面的代码有关,还是我完全错了?
以下为我成功validation:
//compiled with gcc -g -lssl -UOPENSSL_NO_EC SO2228860.c -lcrypto #include // 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 // for ECDSA_do_sign, ECDSA_do_verify #include // for NID_secp192k1 static int create_signature(unsigned char* hash) { int function_status = -1; EC_KEY *eckey=EC_KEY_new(); if (NULL == eckey) { printf("Failed to create new EC Key\n"); function_status = -1; } else { EC_GROUP *ecgroup= EC_GROUP_new_by_curve_name(NID_secp192k1); if (NULL == ecgroup) { printf("Failed to create new EC Group\n"); function_status = -1; } else { int set_group_status = EC_KEY_set_group(eckey,ecgroup); const int set_group_success = 1; if (set_group_success != set_group_status) { printf("Failed to set group for EC Key\n"); function_status = -1; } else { const int gen_success = 1; int gen_status = EC_KEY_generate_key(eckey); if (gen_success != gen_status) { printf("Failed to generate EC Key\n"); function_status = -1; } else { ECDSA_SIG *signature = ECDSA_do_sign(hash, strlen(hash), eckey); if (NULL == signature) { printf("Failed to generate EC Signature\n"); function_status = -1; } else { int verify_status = ECDSA_do_verify(hash, strlen(hash), signature, eckey); const int verify_success = 1; if (verify_success != verify_status) { printf("Failed to verify EC Signature\n"); function_status = -1; } else { printf("Verifed EC Signature\n"); function_status = 1; } } } } EC_GROUP_free(ecgroup); } EC_KEY_free(eckey); } return function_status; } int main( int argc , char * argv[] ) { unsigned char hash[] = "c7fbca202a95a570285e3d700eb04ca2"; int status = create_signature(hash); return(0) ; }
它们是上面代码中的一个小错误。 传递的散列是unsigned char,这个散列CAN中有0x00值! 不要使用strlen(hash)来计算长度,因为如果散列在任何地方都有一个0x00,那么可能会将不正确的长度传递给例程。 哈希是固定长度的,应该这样传递。 例如,sha256的长度应为64。