我编写了一个代码来签署一条显然工作正常的消息,它可以使用DSA私钥(512位)对消息进行签名,然后使用相应的公钥进行验证(此处没有问题)。我使用的是Windows 7。
但是,
如果我想验证控制台中的符号,openssl命令总是返回:验证失败。
#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;
}
输出:
Verification OK
Verification Failure
在DSA_sign,和之前将SHA1应用于摘要(消息) 在DSA_verify之前将SHA1应用于摘要(消息)。
这使得签名在OpenSSL的控制台中兼容。
答案 0 :(得分:-1)
要将DSA与openssl一起使用,您必须将-dss1
传递给dgst,否则它将使用SHA1。试试这个:
system("openssl dgst -dss1 -verify pubkey.pem -signature signature message.txt");