RSA 签名:OpenSSL
我正在尝试使用 Openssl 的 EVP 接口进行编码,以使用 SHA1 进行 RSA 签名。后来我想用不同的摘要算法和不同的签名算法(或者通用的,因此使用 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;
}
I am trying to code with EVP interface of Openssl for RSA signing with SHA1. Later I would like to expand signing with different digest algorithms and different signature algorithms(sor of generic, and therefore the use of EVP).
I seem to get a segmentation fault whenever I try to retrieve the size of my private key
Can someone tell me how to correct this?
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您有几个问题:
PEM_read_PrivateKey()
需要EVP_PKEY **
,而不是RSA **
- 事实上,您不需要 < code>RSA * 对象;EVP_PKEY_assign_RSA()
;EVP_PKEY_set1_RSA()
。要加载私钥,您只需执行以下操作:
您现在可以调用
EVP_PKEY_size(priv_key)
来确定密钥大小。此外,您的
EVP_SignFinal()
调用是错误的 - 您应该传递sig
,而不是&sig
。You have several problems:
PEM_read_PrivateKey()
expects anEVP_PKEY **
, not anRSA **
- in fact, you do not need anRSA *
object at all;EVP_PKEY_assign_RSA()
;EVP_PKEY_set1_RSA()
.To load the private key, you can simply do:
You may now call
EVP_PKEY_size(priv_key)
to determine the key size.Additionally, your
EVP_SignFinal()
call is wrong - you should be passingsig
, not&sig
.我不是该特定库的专家,但仔细阅读了 API 文档后,我认为:
应该是:
同样,您突出显示为 SEGFAULTing 的行不应该引用
priv_key
而不是privkey
另外:如果将变量名称更改为更容易区分的名称(而不是
privkey
和priv_key
,请使用 < code>priv_key_RSA 和priv_key_EVP
拥有仅下划线不同的变量是一个非常坏主意:)
I'm no expert in that particular library, but having perused the API docs, I think this:
should be:
and similarly shouldn't the line you've highlighted as SEGFAULTing refer to
priv_key
notprivkey
also:Both these mistakes would be easier to see if you change your variable names to something easier to distinguish (rather than
privkey
andpriv_key
, usepriv_key_RSA
andpriv_key_EVP
Having variables which differ only in their underscores is a really bad idea :)