我必须使用带有RSA签名的SHA1签署一个数据数组,我的私钥在C中。我正在使用OpenSSl库。但是我总是没有得到OPENSSL_Applink错误。我试过以下:
我正在使用eclipseCDT氧气版。 我是openSSl库中的一个初学者,也想知道如果有人知道这样做的好例子就给我发送链接。我还尝试添加OpenSSL_add_all_digests()和OpenSSL_add_all_algorithms(),但没有成功。
注意:这里的代码可能有误,但我的问题是当编译器遇到openssl库项目崩溃的第一个自定义函数时出现错误而没有OPENSSL_Applink,这是我的主要问题,而不是修复代码本身。
以下是代码段:
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 :(得分:0)
您的代码将&privkey
类型RSA**
传递给PEM_read_PrivateKey
,这需要(根据其原型)EVP_PKEY**
;你的编译器应该已经诊断出来了。同样,EVP_PKEY_size
要求EVP_PKEY*
而不是RSA*
。通过阅读,您根本不需要任何RSA*
,也不需要,且不得使用EVP_PKEY_assign_RSA
。
#include "applink.c"
的所有调用)都在DLL中的EXE 而不是中,那么Applink 应工作 - 是吗?
但是,即使使用动态链接,也可以通过避免使用FILE*
和使用BIO*
表单的API来消除对Applink的需求。因此,而不是:
FILE* f = fopen (file,"r");
if( f==NULL ) ...error...
... PEM_read_PrivateKey (f, &evpkey, NULL, NULL) ...
fclose(f);
使用:
BIO* b = BIO_new_file (file,"r");
if( b==NULL ) ...error...
... PEM_read_bio_PrivateKey (b, &evpkey, NULL, NULL) ...
BIO_close(b);
或可能但更笨重的是:
FILE* f = fopen (file,"r"); if( f==NULL ) ...error...;
char* buf = ...read all data from f into allocated memory...;
int len = ...length of data in buf...;
fclose (f);
BIO* b = BIO_new_mem_buf (buf,len);
... PEM_read_bio_PrivateKey (b, &evpkey, NULL, NULL) ...
... free buf as appropriate ...
PS:我不知道MinGW包是否有手册页,但大多数Windows软件包(Cygwin和现在的WSL除外)都没有。如果不是,您应该书签并使用https://www.openssl.org/docs/manpages.html下的相应目录。