gpt4 book ai didi

c - 如何将 ECDSA SIG 签名转换为 C 中的字符数组

转载 作者:太空宇宙 更新时间:2023-11-04 04:36:34 24 4
gpt4 key购买 nike

我是密码学(openssl 库)的初学者,我需要有关如何通过 C 套接字通信发送 ECDSA 签名的帮助。我的计划是:

  1. 建立套接字连接
  2. 将 ECDSA SIG 对象转换为字符串
  3. 以字符串形式发送签名
  4. 在目的地,将字符串转换回 SIG 对象并验证签名

这是代码。

static ECDSA_SIG* sig = NULL;
static EC_KEY *eckey = NULL;

int main(int argc, char *argv[])
{
unsigned char* msgDigest = "6df19ccf6b89397c9a9906bfd0848f061352e9b5";
if(ECDSAsign())
printf("signed successfully\n");
else
printf("signing failed\n");

...
}

int ECDSAsign()
{
int ret;

eckey = EC_KEY_new_by_curve_name(NID_secp192k1);
if (eckey == NULL)
{
printf(" error ");
return 0;
}

if (!EC_KEY_generate_key(eckey))
{
printf(" error ");
return 0;
}

unsigned char *buffer, *pp;
int bufLen;
bufLen = ECDSA_size(eckey);
buffer = OPENSSL_malloc(bufLen);
pp = buffer;
unsigned char *dgst = "5df19ccf6b89397c9a9906bfd0848f061352e9ba";
sig = ECDSA_do_sign(dgst, strlen(dgst), eckey);
if (sig == NULL)
{
printf(" Signature NOT generated\n ");
return 0;
}

return 1;
}

最佳答案

How to convert ECDSA SIG signature to array of characters in C
...

签名已经是一个字节数组。这就是从 EVP_DigestSignFinal 返回的内容。


一般而言,您希望使用EVP_* 接口(interface)进行签名和验证。以下是来自 EVP Signing and Verifying 上的 OpenSSL wiki。 .

下面的工作是将 ECDSA 放入 EVP_PKEY*。该函数将使用 OPENSSL_malloc 分配签名缓冲区。调用者需要使用 OPENSSL_free 释放它。缓冲区是一个字节数组。

int sign_it(const byte* msg, size_t mlen, byte** sig, size_t* slen, EVP_PKEY* pkey)
{
/* Returned to caller */
int result = -1;

if(!msg || !mlen || !sig || !pkey) {
assert(0);
return -1;
}

if(*sig)
OPENSSL_free(*sig);

*sig = NULL;
*slen = 0;

EVP_MD_CTX* ctx = NULL;

do
{
ctx = EVP_MD_CTX_create();
assert(ctx != NULL);
if(ctx == NULL) {
printf("EVP_MD_CTX_create failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}

const EVP_MD* md = EVP_get_digestbyname("SHA256");
assert(md != NULL);
if(md == NULL) {
printf("EVP_get_digestbyname failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}

int rc = EVP_DigestInit_ex(ctx, md, NULL);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestInit_ex failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}

rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignInit failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}

rc = EVP_DigestSignUpdate(ctx, msg, mlen);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignUpdate failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}

size_t req = 0;
rc = EVP_DigestSignFinal(ctx, NULL, &req);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignFinal failed (1), error 0x%lx\n", ERR_get_error());
break; /* failed */
}

assert(req > 0);
if(!(req > 0)) {
printf("EVP_DigestSignFinal failed (2), error 0x%lx\n", ERR_get_error());
break; /* failed */
}

*sig = OPENSSL_malloc(req);
assert(*sig != NULL);
if(*sig == NULL) {
printf("OPENSSL_malloc failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}

*slen = req;
rc = EVP_DigestSignFinal(ctx, *sig, slen);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignFinal failed (3), return code %d, error 0x%lx\n", rc, ERR_get_error());
break; /* failed */
}

assert(req == *slen);
if(rc != 1) {
printf("EVP_DigestSignFinal failed, mismatched signature sizes %ld, %ld", req, *slen);
break; /* failed */
}

result = 0;

} while(0);

if(ctx) {
EVP_MD_CTX_destroy(ctx);
ctx = NULL;
}

/* Convert to 0/1 result */
return !!result;
}

关于c - 如何将 ECDSA SIG 签名转换为 C 中的字符数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30102116/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com