我正在尝试使用Openssl的EVP接口进行编码,以便使用SHA1进行RSA签名。后来我想用不同的摘要算法和不同的签名算法扩展签名(通用的sor,因此使用EVP)。
每当我尝试检索私钥的大小时,我似乎都会遇到分段错误
有人能告诉我如何纠正这个问题吗?
int rsaSign(char *in_file, char * sig_file){
char *data = NULL;
int data_len;
unsigned int sig_len;
unsigned char *sig;
int err = -1;
OpenSSL_add_all_digests();
FILE *fd;
EVP_PKEY *priv_key = EVP_PKEY_new();
RSA *privkey = NULL;
printf( "we are here..\n");
if ((fd = fopen(PRIVKEY_FILE, "r")) == NULL){
printf("error reading file\n");
exit(0);
}
privkey = RSA_new();
if (!PEM_read_PrivateKey(fd, &privkey, NULL, NULL))
{
fprintf(stderr, "Error loading RSA Private Key File.\n");
return 2;
}
fclose(fd);
if (!EVP_PKEY_assign_RSA (priv_key, privkey))
{
fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
return 3;
}
if (!priv_key) {
printf("no private key\n");
}
EVP_PKEY_set1_RSA(privkey, priv_key);
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
const EVP_MD *md = EVP_get_digestbyname("SHA1");
if (!md) {
fprintf(stderr, "Error creating message digest");
fprintf(stderr, " object, unknown name?\n");
ERR_print_errors_fp(stderr);
exit(1);
}
if (!EVP_SignInit(ctx, md))
{
fprintf(stderr, "EVP_SignInit: failed.\n");
EVP_PKEY_free(priv_key);
return 3;
}
printf( "now to sign update..\n");
data = readFile(in_file);
data_len = strlen(data);
printf("data len = %d\n", data_len);
if (!EVP_SignUpdate(ctx, data, data_len))
{
fprintf(stderr, "EVP_SignUpdate: failed.\n");
EVP_PKEY_free(priv_key);
return 3;
}
printf( "now to sign final..\n");
sig = malloc(EVP_PKEY_size(privkey)); //!!!!! SEGMENTATION FAULT HERE !!!!!
if (!EVP_SignFinal(ctx, &sig, &sig_len, priv_key))
{
fprintf(stderr, "EVP_SignFinal: failed.\n");
free(sig);
EVP_PKEY_free(priv_key);
return 3;
}
free(data);
free(sig);
EVP_PKEY_free(priv_key);
return EXIT_SUCCESS;
}
答案 0 :(得分:7)
我不是那个特定图书馆的专家,但是仔细阅读了API文档后,我想:
EVP_PKEY_set1_RSA(privkey, priv_key);
应该是:
EVP_PKEY_set1_RSA(priv_key, privkey);
同样不应该将您突出显示为SEGFAULTing的行引用priv_key
而不是privkey
:
sig = malloc(EVP_PKEY_size(priv_key));
如果您将变量名更改为更容易区分的内容(而不是privkey
和priv_key
,请使用priv_key_RSA
和priv_key_EVP
<,这些错误会更容易看到/ p>
只有下划线不同的变量是真的坏主意:)
答案 1 :(得分:7)
你有几个问题:
PEM_read_PrivateKey()
需要EVP_PKEY **
,而不是RSA **
- 事实上,您根本不需要RSA *
个对象; EVP_PKEY_assign_RSA()
; EVP_PKEY_set1_RSA()
。要加载私钥,您只需执行以下操作:
EVP_PKEY *priv_key = NULL;
if (!PEM_read_PrivateKey(rsa_pkey_file, &priv_key, NULL, NULL))
{
fprintf(stderr, "Error loading Private Key File.\n");
return 2;
}
您现在可以致电EVP_PKEY_size(priv_key)
来确定密钥大小。
此外,您的EVP_SignFinal()
来电错误 - 您应该通过sig
,而不是&sig
。