C中的DSA签名验证与控制台中的签名验证不匹配。的OpenSSL

 魍魉之波_414 发布于 2023-01-30 07:39

我写了一个代码来对一条消息进行签名,该消息显然运行良好,它可以使用DSA私钥(512位)对消息进行签名,然后稍后使用相应的公钥对其进行验证(这里没有问题)。我正在使用Windows 7。

但,

如果要在控制台中验证标志,则openssl命令始终返回:验证失败。

#include 
#include 
#include 
#include 
#include 

int main(){
    char privkey[] = {
        "-----BEGIN DSA PRIVATE KEY-----\n"
        "MIH4AgEAAkEA3F41fxvcwGZeFxXg2v0/5SR+cxTizT25QugwZgrC7u2zQYTO1Qu0\n"
        "PPDKUrLxkaLzKsUEJbQ1DImnG/FxtRjH7QIVAOp+o1qPhOI4DtnvYS86ynTxhDcF\n"
        "AkAyKbiUxJigARuuVVlGn4emXOtrT+Al+gmKbbVFfkS62RhSZexQ9+mBLv0/1R8T\n"
        "k37AwuybnflijiPjLxB1ZL00AkA2DXjw+0PJOyrQfn2Q44uHyZMG2WfXqT7CIz26\n"
        "ZiIAHDOkZQhOvPLqCKAXfwHgGrgl2JLovhVY8nPMdNk2vJijAhUAzK9TuVobhOE8\n"
        "kU0xl8lqaI/PMyg=\n"
        "-----END DSA PRIVATE KEY-----"
        };

    char pubkey[] = {
        "-----BEGIN PUBLIC KEY-----\n"
        "MIHwMIGoBgcqhkjOOAQBMIGcAkEA3F41fxvcwGZeFxXg2v0/5SR+cxTizT25Qugw\n"
        "ZgrC7u2zQYTO1Qu0PPDKUrLxkaLzKsUEJbQ1DImnG/FxtRjH7QIVAOp+o1qPhOI4\n"
        "DtnvYS86ynTxhDcFAkAyKbiUxJigARuuVVlGn4emXOtrT+Al+gmKbbVFfkS62RhS\n"
        "ZexQ9+mBLv0/1R8Tk37AwuybnflijiPjLxB1ZL00A0MAAkA2DXjw+0PJOyrQfn2Q\n"
        "44uHyZMG2WfXqT7CIz26ZiIAHDOkZQhOvPLqCKAXfwHgGrgl2JLovhVY8nPMdNk2\n"
        "vJij\n"
        "-----END PUBLIC KEY-----"
        };

    char message[] = {"Hello World!"};

    //save message for console test
    FILE *message_file = fopen ("message.txt","w");
    fwrite(message, strlen(message), 1, message_file);
    fclose(message_file);

    //save private key for console test
    FILE *privkey_file = fopen ("privkey.pem","w");
    fwrite(privkey, strlen(privkey), 1, privkey_file);
    fclose(privkey_file);

    //save public key for console test
    FILE *pubkey_file = fopen ("pubkey.pem","w");
    fwrite(pubkey, strlen(pubkey), 1, pubkey_file);
    fclose(pubkey_file);

    //Prepare sign  -----------------------------------------------------

    BIO *priv_bio;
    priv_bio = BIO_new_mem_buf(privkey, -1); 
    if(priv_bio == NULL){ERR_print_errors_fp(stdout);return 1;}

    DSA *private_key;
    private_key = PEM_read_bio_DSAPrivateKey(priv_bio, NULL, NULL, NULL); 
    if(private_key == NULL){ERR_print_errors_fp(stdout);return 2;} 

    unsigned int result, sign_length;
    unsigned char signature[1000] = {0};

    //generate sign
    result = DSA_sign(NULL, (const unsigned char*)message, strlen(message),
                    (unsigned char*)signature, &sign_length, private_key);

    if(result!=1){ERR_print_errors_fp(stdout);return 3;}

    //save signature for console test
    FILE *sign_file = fopen ("signature","wb");
    fwrite((void*)signature, sign_length, 1, sign_file);
    fclose(sign_file);

    //verify sign  -----------------------------------------------------

    BIO *pub_bio;
    pub_bio = BIO_new_mem_buf(pubkey, -1); 
    if(pub_bio == NULL){ERR_print_errors_fp(stdout);return 4;} 

    DSA *public_key;
    public_key = PEM_read_bio_DSA_PUBKEY(pub_bio, NULL, NULL, NULL);
    if(public_key == NULL){ERR_print_errors_fp(stdout);return 5;} 

    result = DSA_verify(NULL, (const unsigned char*)message, strlen(message),
                        signature, sign_length, public_key);

    if(result>0){
        printf("Verification OK\n");
    }else{
        printf("Verification Failure. Error = %i\n",result);
    }

    BIO_free_all(priv_bio);
    DSA_free(private_key);
    DSA_free(public_key);

    //Console verification
    system("openssl dgst -verify pubkey.pem -signature signature message.txt");

    return 0;
}

输出:

Verification OK
Verification Failure

解决了:

使用SHA1算法DSA_sign之前摘要(信息), 使用SHA1算法DSA_verify之前摘要(消息)。

这使签名与OpenSSL在控制台中兼容。

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有