使用C程序验证使用私钥签名的摘要

Ita*_*ela 9 c openssl digest

我将解释到目前为止我所做的所有步骤,并以我的问题结束.

使用OpenSSL 1.0.1e-fips 2013年2月11日

生成私钥和公钥

openssl genrsa -des3 -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
Run Code Online (Sandbox Code Playgroud)

使用摘要和私钥签名消息

openssl dgst -sha256 -sign private.pem -out message.secret message.txt
Run Code Online (Sandbox Code Playgroud)

在这一点上,我有一个公钥,一个签名的消息(带摘要)和原始消息.

第1部分 - 使用CLI(这个工作)

使用CLI我设法验证摘要:

openssl dgst -sha256 -verify public.pem -signature message.secret message.txt
Run Code Online (Sandbox Code Playgroud)

我将"已验证"作为返回值.

第2部分 - 使用C程序

我的程序看起来像这样:

哪里:

msg是message.txt

签名是message.secret

pkey是公钥(使用PEM_read_PUBKEY实现)

int verify_it(const byte* msg, size_t msg_len, byte* signature, EVP_PKEY* pkey) {
    EVP_MD_CTX      *ctx;
    size_t          sig_len;
    int             bool_ret;
    int             ret_val;

    ret_val = EXIT_SUCCESS;
    ctx = NULL;

    do
    {
        ctx = EVP_MD_CTX_create();    
        const EVP_MD* md = EVP_get_digestbyname( "SHA256" );

        EVP_DigestInit_ex( ctx, md, NULL );
        EVP_DigestVerifyInit( ctx, NULL, md, NULL, pkey );
        EVP_DigestVerifyUpdate(ctx, msg, msg_len);

        sig_len = 256;            
        if ( !EVP_DigestVerifyFinal( ctx, signature, sig_len ) 
                ERR_print_errors_fp( stdout )
        );

    } while(0);

    return ret_val;

}
Run Code Online (Sandbox Code Playgroud)

此代码返回验证失败(值为0).

函数ERR_print_errors_fp(stdout)也会打印以下消息:

140332412258152:error:04091077:lib(4):func(145):reason(119):rsa_sign.c:176
Run Code Online (Sandbox Code Playgroud)

编辑

感谢@deniss我已经设法解决了这个问题(签名长度很差 - 可能是'\ 0'中间签名 - 所以我只编辑长度为256)

但现在我又遇到了另一个问题 -

140195987986280:error:04091068:lib(4):func(145):reason(104):rsa_sign.c:293
Run Code Online (Sandbox Code Playgroud)

用openssl errstr检查它我有

error:04091068:rsa routines:INT_RSA_VERIFY:bad signature
Run Code Online (Sandbox Code Playgroud)

我获得签名的方式是这样的:

secret_fp = fopen( "message.secret", "rb" );
fseek( secret_fp, 0, SEEK_END );
file_len = ftell( secret_fp );
fseek( secret_fp, 0, SEEK_SET );

signature = malloc( file_len );
fread( signature, file_len, 1, secret_fp );
Run Code Online (Sandbox Code Playgroud)

小智 5

您始终可以将openssl错误代码解码为有意义的消息

openssl errstr <error-code>
Run Code Online (Sandbox Code Playgroud)

代码04091077代表error:04091077:rsa routines:INT_RSA_VERIFY:wrong signature length.

最可能的解释:

  • message.secret是二进制文件

  • 它在中间某处有零字节

  • strlen 修剪此字节上的签名