The DSA signature verification in C does not match the signature verification on the console. OpenSSL (enabled)

I wrote code to sign the message, which seems to work just fine, it can sign the message with the DSA private key (512 bits) and check it later using the corresponding public key (no problem here). I am using Windows 7.

But,

If I want to check a character in the console, the openssl command always returns: Validation error.

Some ideas? Thanks.

#include <stdio.h>
#include <string.h>
#include <openssl\dsa.h>
#include <openssl\engine.h>
#include <openssl\pem.h>

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;
}

Exit:

Verification OK
Verification Failure

It is decided:

Apply SHA1 to the digest (message) before DSA_sign, and apply SHA1 to the digest (message) before DSA_verify.

This allows signature compatibility to work in the console with OpenSSL.

+4
1

DSA openssl, -dss1 dgst, SHA1. :

system("openssl dgst -dss1 -verify pubkey.pem -signature signature message.txt");
-1

Source: https://habr.com/ru/post/1524799/


All Articles