Openssl 如何读取用于HMAC_Init_ex()的密钥文件
我使用openssl生成了一个RSA私钥 我需要使用普通C中OpenSSL库的HMAC_*()函数对数据进行哈希/签名,但我不确定如何正确地从该文件中提取私钥数据 据我所知,该文件是B64编码的,所以我将其解压缩并存储在缓冲区中。然而,在我看来,HMAC_*()函数,尽管散列和签名不使用实际的密钥,因为结果不是我所期望的 我想我应该放弃标题?或者用户函数读取密钥而不是自己做 我来这里是因为我读了PrivateKey(),但是它创建了一个EVP_PKEY结构,它不能直接由HMAC*()函数使用 有什么提示吗?Openssl 如何读取用于HMAC_Init_ex()的密钥文件,openssl,rsa,Openssl,Rsa,我使用openssl生成了一个RSA私钥 我需要使用普通C中OpenSSL库的HMAC_*()函数对数据进行哈希/签名,但我不确定如何正确地从该文件中提取私钥数据 据我所知,该文件是B64编码的,所以我将其解压缩并存储在缓冲区中。然而,在我看来,HMAC_*()函数,尽管散列和签名不使用实际的密钥,因为结果不是我所期望的 我想我应该放弃标题?或者用户函数读取密钥而不是自己做 我来这里是因为我读了PrivateKey(),但是它创建了一个EVP_PKEY结构,它不能直接由HMAC*()函数使用 有
谢谢 你误解了HMAC。HMAC使用共享(对称)密钥创建数据的安全密钥散列。它需要与生成的密钥相同的密钥来验证它(这不是签名)。密钥只是一个没有特定结构的随机位序列 RSA签名基于普通的、未加密的散列。您应该使用
EVP\u SignInit()
/EVP\u SignUpdate()
/EVP\u SignFinal()
函数来创建RSA签名。例如,要初始化RSA-with-SHA256签名的EVP上下文,您需要执行以下操作:
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
EVP_SignInit(&ctx, EVP_sha256());
(如果您的OpenSSL版本不包括SHA256,您可以使用EVP_sha1()
进行RSA-with-sha1签名)
要获取EVP\u SignFinal()
所需的EVP\u PKEY*
,您需要从RSA密钥对其进行初始化:
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_PKEY_set1_RSA(pkey, rsakey);
由openssl
命令行实用程序创建的base64编码RSA密钥是PEM格式的,因此您可以使用PEM\u read\u RSAPrivateKey()
将其直接从文件读取到RSA*
句柄中
下面是一个读取RSA私钥文件并使用它生成另一个文件签名的示例:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
int do_evp_sign(FILE *rsa_pkey_file, FILE *in_file)
{
RSA *rsa_pkey = NULL;
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_MD_CTX ctx;
unsigned char buffer[4096];
size_t len;
unsigned char *sig;
unsigned int siglen;
int i;
if (!PEM_read_RSAPrivateKey(rsa_pkey_file, &rsa_pkey, NULL, NULL))
{
fprintf(stderr, "Error loading RSA Private Key File.\n");
return 2;
}
if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey))
{
fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
return 3;
}
EVP_MD_CTX_init(&ctx);
if (!EVP_SignInit(&ctx, EVP_sha1()))
{
fprintf(stderr, "EVP_SignInit: failed.\n");
EVP_PKEY_free(pkey);
return 3;
}
while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0)
{
if (!EVP_SignUpdate(&ctx, buffer, len))
{
fprintf(stderr, "EVP_SignUpdate: failed.\n");
EVP_PKEY_free(pkey);
return 3;
}
}
if (ferror(in_file))
{
perror("input file");
EVP_PKEY_free(pkey);
return 4;
}
sig = malloc(EVP_PKEY_size(pkey));
if (!EVP_SignFinal(&ctx, sig, &siglen, pkey))
{
fprintf(stderr, "EVP_SignFinal: failed.\n");
free(sig);
EVP_PKEY_free(pkey);
return 3;
}
printf("Signature: \n");
for (i = 0; i < siglen; i++)
{
printf("%02x", sig[i]);
if (i % 16 == 15)
printf("\n");
}
printf("\n");
free(sig);
EVP_PKEY_free(pkey);
return 0;
}
#包括
#包括
#包括
#包括
#包括
int do_evp_签名(文件*rsa_pkey_文件,文件*in_文件)
{
RSA*RSA_pkey=NULL;
EVP_PKEY*PKEY=EVP_PKEY_new();
执行副总裁MD CTX CTX;
无符号字符缓冲区[4096];
尺寸透镜;
无符号字符*sig;
无符号整数符号;
int i;
if(!PEM_read_RSAPrivateKey(rsa_pkey_文件和rsa_pkey,NULL,NULL))
{
fprintf(stderr,“加载RSA私钥文件时出错。\n”);
返回2;
}
如果(!EVP_PKEY_assign_RSA(PKEY,RSA_PKEY))
{
fprintf(标准,“EVP\u PKEY\u assign\u RSA:失败。\n”);
返回3;
}
EVP_MD_CTX_init(&CTX);
如果(!EVP_SignInit(&ctx,EVP_sha1()))
{
fprintf(标准,“执行副总裁签名:失败。\n”);
免费执行副总裁(PKEY);
返回3;
}
而((len=fread(buffer,1,sizeof buffer,in_file))>0)
{
if(!EVP_SignUpdate(&ctx,buffer,len))
{
fprintf(标准,“EVP\U SignUpdate:失败。\n”);
免费执行副总裁(PKEY);
返回3;
}
}
如果(ferror(在文件中))
{
perror(“输入文件”);
免费执行副总裁(PKEY);
返回4;
}
sig=malloc(执行副总裁(PKEY)尺寸(PKEY));
如果(!EVP_SignFinal(&ctx,sig,&siglen,pkey))
{
fprintf(标准,“EVP\U SignFinal:失败。\n”);
免费(sig);
免费执行副总裁(PKEY);
返回3;
}
printf(“签名:\n”);
对于(i=0;i