使用C例程和openssl dgst、rsautl命令时的不同签名

使用C例程和openssl dgst、rsautl命令时的不同签名,c,openssl,rsa,signature,C,Openssl,Rsa,Signature,我使用以下语句创建RSA公钥和私钥 openssl genrsa-out ksign_private.pem 1024 openssl rsa-in ksign_private.pem-pubout>ksign_public.pem 然后我有一个程序,它使用openssl libcrypto中的PEM_read_RSAPrivateKey、EVP_PKEY_assign_RSA、EVP_SignInit、EVP_SignUpdate、EVP_SignFinal函数生成签名文件 我还有一个例行程序

我使用以下语句创建RSA公钥和私钥

openssl genrsa-out ksign_private.pem 1024 openssl rsa-in ksign_private.pem-pubout>ksign_public.pem

然后我有一个程序,它使用openssl libcrypto中的PEM_read_RSAPrivateKey、EVP_PKEY_assign_RSA、EVP_SignInit、EVP_SignUpdate、EVP_SignFinal函数生成签名文件

我还有一个例行程序可以验证签名是否可以使用PEM_read_RSA_PUBKEY、EVP_PKEY_assign_RSA、EVP_VerifyInit、EVP_VerifyUpdate、EVP_VerifyFinal进行验证。 这些例程的源代码附在下面

当使用这些函数时,我可以创建SHA1签名,用私钥加密,用公钥解密

然而,我尝试使用相同的数据文件、相同的私有密钥和使用openssl rsautl的公钥,并且openssl rsautl创建的签名大不相同

openssl dgst -sha1 -binary < myData > testfile.sha1
openssl rsautl -sign -in testfile.sha1 -inkey ksign_private.pem -keyform PEM -out testfile.sig
openssldgst-sha1-binarytestfile.sha1
openssl rsautl-sign-in testfile.sha1-inkey ksign_private.pem-keyform pem-out testfile.sig
有谁能告诉我,在使用openssl rsautl或dgst命令时,我使用了哪些错误的选项

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <openssl/sha.h>
#include <errno.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

int ksignEvpSign(FILE * private_key, FILE * inFileFP, FILE * outFileFP);
int ksignEvpVerify(FILE * public_key, FILE * dataFileFP, FILE * signFileFP);

int ksignEvpSign(FILE * privateKeyFP, FILE * inFileFP, FILE * outFileFP)
{
    RSA *rsa_pkey = NULL;
    EVP_PKEY *pkey = EVP_PKEY_new();
    EVP_MD_CTX ctx;
    unsigned char buffer[4096];
    size_t len;
    unsigned char *sig;
    unsigned int siglen;

    if (!PEM_read_RSAPrivateKey(privateKeyFP, &rsa_pkey, NULL, NULL)) {
        fprintf(stderr, "Error loading RSA Private Key File.\n");
        return 2;
    }

    if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey)) {
        fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
        return 3;
    }

    EVP_MD_CTX_init(&ctx);

    if (!EVP_SignInit(&ctx, EVP_sha1())) {
        fprintf(stderr, "EVP_SignInit: failed.\n");
        EVP_PKEY_free(pkey);
        return 3;
    }

    while ((len = fread(buffer, 1, sizeof buffer, inFileFP)) > 0) {
        if (!EVP_SignUpdate(&ctx, buffer, len)) {
            fprintf(stderr, "EVP_SignUpdate: failed.\n");
            EVP_PKEY_free(pkey);
            return 3;
        }
    }

    if (ferror(inFileFP)) {
        perror("input file");
        EVP_PKEY_free(pkey);
        return 4;
    }

    sig = malloc(EVP_PKEY_size(pkey));
    if (!EVP_SignFinal(&ctx, sig, &siglen, pkey)) {
        fprintf(stderr, "EVP_SignFinal: failed.\n");
        free(sig);
        EVP_PKEY_free(pkey);
        return 3;
    }
    fwrite(sig, siglen, 1, outFileFP);
    free(sig);
    EVP_PKEY_free(pkey);
    return 0;
}

int ksignEvpVerify(FILE * publicKeyFP, FILE * dataFileFP, FILE * sigFileFP)
{
    RSA *rsa_pkey = NULL;
    EVP_PKEY *pkey;
    EVP_MD_CTX ctx;
    unsigned char buffer[4096];
    size_t len;
    unsigned char *sig;
    unsigned int siglen;
    struct stat stat_buf;

    if (!PEM_read_RSA_PUBKEY(publicKeyFP, &rsa_pkey, NULL, NULL)) {
        fprintf(stderr, "Error loading RSA public Key File.\n");
        return 2;
    }
    pkey = EVP_PKEY_new();

    if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey)) {
        fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
        return 3;
    }
    /* Read the signature */
    if (fstat(fileno(sigFileFP), &stat_buf) == -1) {
        fprintf(stderr, "Unable to read signature \n");
        return 4;
    }
    siglen = stat_buf.st_size;
    sig = (unsigned char *)malloc(siglen);
    if (sig == NULL) {
        fprintf(stderr, "Unable to allocated %d bytes for signature\n",
            siglen);
        return 5;
    }
    if ((fread(sig, 1, siglen, sigFileFP)) != siglen) {
        fprintf(stderr, "Unable to read %d bytes for signature\n",
            siglen);
        return 6;
    }
/*
    printf("Signature:");
    for (i = 0; i < siglen; i++) {
        fprintf(stdout, "%02x", sig[i]);
        if (i % 16 == 15)
            fprintf(stdout, "\n");
    }
    fprintf(stdout, "\n");
*/

    EVP_MD_CTX_init(&ctx);

    if (!EVP_VerifyInit(&ctx, EVP_sha1())) {
        fprintf(stderr, "EVP_SignInit: failed.\n");
        EVP_PKEY_free(pkey);
        return 7;
    }

    while ((len = fread(buffer, 1, sizeof buffer, dataFileFP)) > 0) {
        if (!EVP_VerifyUpdate(&ctx, buffer, len)) {
            fprintf(stderr, "EVP_SignUpdate: failed.\n");
            EVP_PKEY_free(pkey);
            return 8;
        }
    }

    if (ferror(dataFileFP)) {
        perror("input file");
        EVP_PKEY_free(pkey);
        return 9;
    }

    if (!EVP_VerifyFinal(&ctx, sig, siglen, pkey)) {
        fprintf(stderr, "EVP_VerifyFinal: failed.\n");
        free(sig);
        EVP_PKEY_free(pkey);
        return 10;
    }
    free(sig);
    EVP_PKEY_free(pkey);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int ksignEvpSign(文件*私钥,文件*inFileFP,文件*outFileFP);
int ksignEvpVerify(文件*公钥,文件*数据文件FP,文件*签名文件FP);
int ksignEvpSign(文件*privateKeyFP,文件*inFileFP,文件*outFileFP)
{
RSA*RSA_pkey=NULL;
EVP_PKEY*PKEY=EVP_PKEY_new();
执行副总裁MD CTX CTX;
无符号字符缓冲区[4096];
尺寸透镜;
无符号字符*sig;
无符号整数符号;
if(!PEM_read_rsaprovatekey(privateKeyFP和rsa_pkey,NULL,NULL)){
fprintf(stderr,“加载RSA私钥文件时出错。\n”);
返回2;
}
如果(!EVP_PKEY_assign_RSA(PKEY,RSA_PKEY)){
fprintf(标准,“EVP\u PKEY\u assign\u RSA:失败。\n”);
返回3;
}
EVP_MD_CTX_init(&CTX);
如果(!EVP_SignInit(&ctx,EVP_sha1())){
fprintf(标准,“执行副总裁签名:失败。\n”);
免费执行副总裁(PKEY);
返回3;
}
而((len=fread(buffer,1,sizeof buffer,inFileFP))>0){
if(!EVP_SignUpdate(&ctx,buffer,len)){
fprintf(标准,“EVP\U SignUpdate:失败。\n”);
免费执行副总裁(PKEY);
返回3;
}
}
if(铁合金(填充){
perror(“输入文件”);
免费执行副总裁(PKEY);
返回4;
}
sig=malloc(执行副总裁(PKEY)尺寸(PKEY));
如果(!EVP_SignFinal(&ctx,sig,&siglen,pkey)){
fprintf(标准,“EVP\U SignFinal:失败。\n”);
免费(sig);
免费执行副总裁(PKEY);
返回3;
}
fwrite(sig,siglen,1,outFileFP);
免费(sig);
免费执行副总裁(PKEY);
返回0;
}
int ksignEvpVerify(文件*publicKeyFP,文件*dataFileFP,文件*sigFileFP)
{
RSA*RSA_pkey=NULL;
执行副总裁*PKEY;
执行副总裁MD CTX CTX;
无符号字符缓冲区[4096];
尺寸透镜;
无符号字符*sig;
无符号整数符号;
结构统计;
if(!PEM_read_RSA_PUBKEY(publicKeyFP和RSA_pkey,NULL,NULL)){
fprintf(stderr,“加载RSA公钥文件时出错。\n”);
返回2;
}
pkey=EVP_pkey_new();
如果(!EVP_PKEY_assign_RSA(PKEY,RSA_PKEY)){
fprintf(标准,“EVP\u PKEY\u assign\u RSA:失败。\n”);
返回3;
}
/*读签名*/
如果(fstat(fileno(sigFileFP),&stat_buf)=-1){
fprintf(stderr,“无法读取签名”);
返回4;
}
siglen=统计数据和标准尺寸;
sig=(无符号字符*)malloc(siglen);
if(sig==NULL){
fprintf(stderr,“无法为签名分配%d字节”\n,
西格伦);
返回5;
}
if((fread(sig,1,siglen,sigFileFP))!=siglen){
fprintf(stderr,“无法读取签名的%d字节”\n“,
西格伦);
返回6;
}
/*
printf(“签名:”);
对于(i=0;i0){
如果(!EVP_VerifyUpdate(&ctx,缓冲区,len)){
fprintf(标准,“EVP\U SignUpdate:失败。\n”);
免费执行副总裁(PKEY);
返回8;
}
}
if(ferror(数据文件FP)){
perror(“输入文件”);
免费执行副总裁(PKEY);
返回9;
}
if(!EVP_VerifyFinal(&ctx,sig,siglen,pkey)){
fprintf(标准,“EVP_VerifyFinal:失败。\n”);
免费(sig);
免费执行副总裁(PKEY);
返回10;
}
免费(sig);
免费执行副总裁(PKEY);
返回0;
}

由于
pkeyutl
可以处理任何算法,因此应首选
pkeyutl
命令。要在命令行上获得相同的签名,应使用以下命令:

openssl pkeyutl -sign -in testfile.sha1 -inkey ksign_private.pem -pkeyopt digest:sha1 -outfile testfile.sig

重要的部分是告诉
openssl
您正在使用摘要值。否则它似乎是在为摘要签名。

您可以直接使用
dgst
命令对数据进行散列和签名,如:

openssldgst-sha1-binary-signprivkey.pemmySignature


有关所有选项,请参阅。

rsautl上的源代码是否已弃用?谷歌搜索把我带回到这个页面。@cgmb:谢谢,糟糕的词语选择。我想我从描述段落的第二行中得到了不赞成的印象:加上
pkyutl
更普遍/更受欢迎。如果没有
-pkeyopt digest
,问题不是“签署摘要”,而是跳过AS