如何以编程方式在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
。
我要做的是使用我的私钥加密{{1}}中包含的消息,以便只有公钥才能解密它。这可能与上面的代码有关,还是我完全错了?
答案 0 :(得分:7)
以下为我成功验证:
//compiled with gcc -g -lssl -UOPENSSL_NO_EC SO2228860.c -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
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) ;
}
答案 1 :(得分:2)
它们是上面代码中的一个小错误。传递的哈希是一个无符号字符,该哈希中可以有0x00的值!不要使用strlen(hash)来计算长度,因为如果哈希值在任何地方都为0x00,则可能会将错误的长度传递给例程。哈希值是固定长度的,应这样传递。例如sha256的长度应为64。