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!"};
FILE *message_file = fopen ("message.txt","w");
fwrite(message, strlen(message), 1, message_file);
fclose(message_file);
FILE *privkey_file = fopen ("privkey.pem","w");
fwrite(privkey, strlen(privkey), 1, privkey_file);
fclose(privkey_file);
FILE *pubkey_file = fopen ("pubkey.pem","w");
fwrite(pubkey, strlen(pubkey), 1, pubkey_file);
fclose(pubkey_file);
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};
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;}
FILE *sign_file = fopen ("signature","wb");
fwrite((void*)signature, sign_length, 1, sign_file);
fclose(sign_file);
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);
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.