gpt4 book ai didi

c - 如何使用 libssl 对文件进行签名?

转载 作者:行者123 更新时间:2023-11-30 16:00:24 26 4
gpt4 key购买 nike

我想使用 OpenSSL 为文件创建签名。我相信我的结果应该与 openssl 生成的 testfile.sig 相匹配:

$ openssl dgst -sha1 -binary < testfile > testfile.sha1
$ openssl rsautl -sign -in testfile.sha1 -inkey rsa_private.pem -keyform PEM -out testfile.sig

$ openssl rsautl -verify -inkey rsa_public.pem -pubin -in testfile.sig -hexdump
Loading 'screen' into random state - done
0000 - 9f 23 88 15 2b af d6 a6-9f 4f 1f 7e ee b0 90 dd .#..+....O.~....
0010 - 69 99 2b 3d i.+=

所以,我使用了caf发布在这里的代码: How to read key file for use with HMAC_Init_ex()只是添加了一小块来将 EVP_SignFinal() 之后的数据保存到文件中,所以我可以用 openssl 和公钥验证它:

FILE * fp = fopen("out.sig", "wb");
if (fp) {
printf("Writing the signature in a file. # of bytes: %u.\n", sig_len);
fwrite(sig, 1, sig_len, fp);
fclose(fp);
}

令我惊讶的是,我得到了这个:

$ openssl rsautl -verify -inkey rsa_public.pem -pubin -in out.sig -hexdump
Loading 'screen' into random state - done
0000 - 30 21 30 09 06 05 2b 0e-03 02 1a 05 00 04 14 9f 0!0...+.........
0010 - 23 88 15 2b af d6 a6 9f-4f 1f 7e ee b0 90 dd 69 #..+....O.~....i
0020 - 99 2b 3d .+=

现在,如果您观察 out.sig 验证的输出,您将看到最后 20bytes 与 testfile.sig 验证的数据输出相匹配。这 20 个字节是确实是我文件的 SHA-1 哈希值。但开头的前 15 个字节是什么?EVP_SignInit()/EVP_SignUpdate()/EVP_SignFinal() 不应该只将哈希值放入消息,还是我遗漏了一些明显的东西?

如果您需要更多信息,请告诉我。谢谢

用于签署文件的完整函数:

int do_evp_sign(FILE * rsa_pkey_file, FILE * in_file)
{
OpenSSL_add_all_digests();
ERR_load_crypto_strings();

EVP_PKEY * pkey = PEM_read_PrivateKey(rsa_pkey_file, NULL, NULL, NULL);
if (pkey == NULL) {
ERR_print_errors_fp(stderr);
return 1;
}

fseek(in_file, 0, SEEK_END);
const size_t lSize = ftell(in_file);
rewind(in_file);

EVP_MD_CTX md_ctx;
EVP_SignInit(&md_ctx, EVP_sha1());

size_t len;
unsigned char buffer[4096];

size_t bytesLeft = lSize;
while (bytesLeft > 0) {
const size_t count = (bytesLeft > sizeof(buffer) ? sizeof(buffer) : bytesLeft);
len = fread(buffer, 1, count, in_file);
if (len != count) {
fprintf(stderr, "Read error! len (%u) != count (%u).\n", len, count);
EVP_PKEY_free(pkey);
return 1;
}
if (!EVP_SignUpdate(&md_ctx, buffer, len))
{
ERR_print_errors_fp(stderr);
EVP_PKEY_free(pkey);
return 1;
}
bytesLeft -= len;
}

unsigned int sig_len;
unsigned char * sig = (unsigned char *)malloc(EVP_PKEY_size(pkey));

if (!sig) {
fprintf(stderr, "Couldn't allocate %u bytes of memory.\n", EVP_PKEY_size(pkey));
EVP_PKEY_free(pkey);
return 1;
}

if (!EVP_SignFinal(&md_ctx, sig, &sig_len, pkey))
{
ERR_print_errors_fp(stderr);
EVP_PKEY_free(pkey);
free(sig);
return 1;
}

FILE * fTemp = fopen("out.sig", "wb");
if (fTemp) {
printf("Writing the signature to a file. Number of bytes: %u.\n", sig_len);
fwrite(sig, 1, sig_len, fTemp);
fclose(fTemp);
}

printf("Signature: \n");
for (unsigned int i = 0; i != sig_len; ++i)
{
printf("%02x", sig[i]);
if (i % 16 == 15)
printf("\n");
}
printf("\n");

EVP_PKEY_free(pkey);
free(sig);

return 0;
}

最佳答案

您拥有的是哈希值的 ASN.1 编码。

0000 - 30 21 30 09 06 05 2b 0e-03 02 1a 05 00 04 14 9f   0!0...+.........
0010 - 23 88 15 2b af d6 a6 9f-4f 1f 7e ee b0 90 dd 69 #..+....O.~....i
0020 - 99 2b 3d .+=

30 - SEQUENCE
21 - length (33 bytes)
30 - SEQUENCE
09 - length (9 bytes)
06 - OID
05 - length (5 bytes)
2b 0e 03 02 1a = 1 2 14 3 2 26 = SHA-1
05 - NULL
00 - length (0 bytes)
04 - Octet String
14 - length (20 bytes)
9f ... 3d - contents (the digest)

您到底是如何生成摘要的(以代码形式)?看起来您使用的任何内容都将其转换为 ASN.1,而不是保留“原始”,这就是您签名的内容。

关于c - 如何使用 libssl 对文件进行签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7781069/

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