使用 SHA1 和 C 中的 RSA 对数据数组进行签名



我必须使用带有 RSA 签名的 SHA1 对数据数组进行签名,并使用 C 格式的私钥。我正在使用OpenSSl库。但是我总是没有OPENSSL_Applink错误。我尝试了以下方法:

  • 包括 applink.c
  • 静态链接库仅 libcrypto-1_1.a
  • 调试 applink.c 以查看表的问题
  • 由于我不能包含 Applink.c,因此我在项目中手动添加了相同文件名的源代码,这导致应用程序无响应。

我正在使用日食CDT氧气版本。 我是 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 filen");
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 keyn");
}
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 = %dn", 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;
}

你的代码&privkey类型RSA**传递给需要(根据其原型)EVP_PKEY**PEM_read_PrivateKey; 你的编译器应该已经诊断出了这一点。同样EVP_PKEY_size要求EVP_PKEY*而不是RSA*。使用通用读取,您根本不需要任何RSA*,也不需要也不得使用EVP_PKEY_assign_RSA.

如果您的代码(包括对OpenSSL和#include "applink.c"的所有调用)在EXE中而不是在DLL中,Applink应该可以工作 - 是吗?

但是,即使使用动态链接,您也可以通过避免使用FILE*的 API 并使用BIO*表单来消除对 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 下的相应目录。

最新更新