在C中使用带RSA的SHA1对数据数组进行签名
我必须使用带有RSA签名的SHA1对数据数组进行签名,并使用C语言的私钥。我使用的是OpenSSl库。但是,我始终没有收到OPENSSL\u Applink错误。我尝试过以下方法:在C中使用带RSA的SHA1对数据数组进行签名,c,openssl,rsa,sha1,C,Openssl,Rsa,Sha1,我必须使用带有RSA签名的SHA1对数据数组进行签名,并使用C语言的私钥。我使用的是OpenSSl库。但是,我始终没有收到OPENSSL\u Applink错误。我尝试过以下方法: 包括applink.c 静态链接库仅限libcrypto-1_1.a 调试applink.c以查看表的问题 因为我没有包含applink.c,所以我在我的项目中手动添加了同一文件名中的源代码,这导致了一个无响应的应用程序 我用的是eclipseCDT氧气版。 我是一个openSSl库的乞丐,如果有人知道这样做的好
- 包括applink.c
- 静态链接库仅限libcrypto-1_1.a
- 调试applink.c以查看表的问题
- 因为我没有包含applink.c,所以我在我的项目中手动添加了同一文件名中的源代码,这导致了一个无响应的应用程序
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;
}
您的代码将
&PrivateKey
类型RSA**
传递到PEM_read_PrivateKey
,这需要(根据其原型)EVP_PKEY**
;您的编译器应该已经对此进行了诊断。类似地,EVP\u PKEY\u size
要求EVP\u PKEY*
不RSA*
。使用泛型read,您根本不需要任何RSA*
,也不需要也不能使用EVP\u PKEY\u assign\u RSA
如果您的代码(包括对OpenSSL的所有调用和#include“Applink.c”
)在EXE中而不是在DLL中,则Applink应该可以工作,是吗
但是,通过避免使用FILE*
和BIO*
表单的API,即使使用动态链接,也可以消除对Applink的需求。因此,不是:
FILE* f = fopen (file,"r");
if( f==NULL ) ...error...
... PEM_read_PrivateKey (f, &evpkey, NULL, NULL) ...
fclose(f);
使用:
或者可能,但更笨重:
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)没有。如果没有,您可能应该将它们添加到书签并使用下的相应目录。您说您不能链接到
libssl
(例如,链接到-lssl-lcrypto
)?我可以链接它们或任何其他,但我的目标是静态链接它们,因为我读到如果您在我的案例中使用dll(没有OPENSSL\u Applink)会出现问题也许我忘了提到,我的程序是单线程的,当我调试时,我注意到它使用多线程,所以这可能是个问题吗?嗯,这通常只是一个问题,如果你想分发你的代码。Eclipse应该可以设置正确的环境来查找.dll库(这告诉我您在windoze上)。这就是根据您使用的是VS还是MinGW而存在许多差异的地方(MinGW的版本也存在差异)。你可能想看看指南。谢谢,是的,我使用windoze,MingW3.4.5版本,是的,我想分发代码。您认为问题可能是我使用的是预编译版本的openssl吗?谢谢,当我静态编译openssl库并传递仅链接器存档(.a)文件时,我的问题已经解决了。
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 ...