使用OpenSSL和Visual Studio验证SHA-1签名

时间:2015-12-28 21:43:23

标签: c++ visual-c++ openssl

我尝试了一天以上,但仍然无法让它发挥作用。

我正在尝试使用RSA签名验证XML文件。我让它在C#dotNET应用程序中工作但我需要在没有dotNET的情况下使用C ++。

不知怎的,我无法在我的程序中验证签名。在openssl命令行上它工作得很好。请给我一个关于我可能缺少什么的提示。谢谢!

这是我到目前为止所做的:

HelloData.txt:

Hello

HalloSignHash.sha1:

k„“D⁄�.‡f�*÷?5¶¥;È›h„ëßÚœ¨YNº‚Â1)îZ6›?@6©ØÍØC˛¨IblˇVt„N¥df!ˆn’”ø>±∏p*Öîhäå1ô∆:V‹
ßáJ†ÉY¶V+6ö\ìÒÜ…&~¥∑&º8ó<T„

key.pub:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCDrL6sGxBjjeb6eVdDNQtKFZw5
K0VGAOdOlCFnIo7puazkeTKJ8TY7a0KG3fcFWXLoyxNAvocZLvQTmX2pSfl28XWq
TL3kgzouYJzVdbG1mX7B/LqQAlfhuzIJyqPK+C0uYkIESvJRDWqN2nji9oIb179u
Y2YYQRGMrmF/FxDZvwIDAQAB
-----END PUBLIC KEY-----

OpenSSL的:

openssl dgst -sha1 -verify TestCert.pem -signature HalloSignHash.sha1 HelloData.txt

openssl dgst -sha1 -verify key.pub -signature HalloSignHash.sha1 HelloData.txt

Verified OK

OpenSSLCryptoSample.cpp:

#include "stdafx.h"
#include <iostream>
#include <string>
#include "osslcrypto.h"

#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#include <openssl/rsa.h>
#include <openssl/sha.h>

#include <openssl/bio.h>

#include <openssl/err.h>

#include <iostream>
#include <fstream>

using namespace std;


#define MAX_LEN 256


//----------------------------------------------------------------------


int _tmain(int argc, _TCHAR* argv[])
{
//
// Local variables definition
//
const char      cert_filestr[] = "./TestCert.pem";
EVP_PKEY*       evpkey = NULL;
BIO*            certbio = NULL;
X509*           cert = NULL;
EVP_MD_CTX*     ctx = NULL;
unsigned char   sigBuf[MAX_LEN] = { 0 };
char            msg[] = "Hello";
int             bufSize = sizeof(msg);
int             ret = 1;
int             bytesRet = 0;

OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();


//
//  These function calls initialize openssl for correct work
//
ERR_load_BIO_strings();
ERR_load_crypto_strings();


//
//  Create the Input/Output BIO's
//
certbio = BIO_new(BIO_s_file());


//
// Loading the certificate from file (PEM)
//
ret = BIO_read_filename(certbio, cert_filestr);
cert = PEM_read_bio_X509(certbio, NULL, 0, NULL);

if (NULL == cert)
{
    printf("Error loading cert from the .pem file!\n");
} // if
else
{
    printf("Certificate loaded from the .pem file\n\n");
}


//
// Extract the certificate's public key data
//
evpkey = X509_get_pubkey(cert);
if (NULL == evpkey)
{
    printf("Error getting public key from certificate\n");
} // if
else
{
    printf("Public key extracted from the certificate\n\n");
}


//
// Read signed HASH from file

FILE * pFile;
long lSize;
char * buffer;
size_t result;

pFile = fopen("Test", "rb");
if (pFile == NULL) { fputs("File error", stderr); exit(1); }

// obtain file size:
fseek(pFile, 0, SEEK_END);
lSize = ftell(pFile);
rewind(pFile);

// allocate memory to contain the whole file:
buffer = (char*)malloc(sizeof(char)*lSize);
if (buffer == NULL) { fputs("Memory error", stderr); exit(2); }

// copy the file into the buffer:
result = fread(buffer, 1, lSize, pFile);
if (result != lSize) { fputs("Reading error", stderr); exit(3); }

/* the whole file is now loaded in the memory buffer. */
for (size_t i = 0; i < lSize; i++)
{
    sigBuf[i] = buffer[i];
}
bytesRet = lSize;

// terminate
fclose(pFile);
free(buffer);

// Print signature buffer
printf("Data in the signed buffer is : %s\n\n", sigBuf);


//
// Allocating memory for EVP_MD_CTX Context object
//
ctx = (EVP_MD_CTX *)malloc(sizeof(EVP_MD_CTX));
if (NULL == ctx)
{
    printf("Memory is not allocated for EVP_MD_CTX object\n");
} // if
else
{
    printf("Memory allocated for EVP_MD_CTX object\n\n");
}


//
// Initializing EVP_MD_CTX Context object
EVP_MD_CTX_init(ctx);


//
// Calling EVP_VerifyInit_ex() function to initialize context
// for verification
//
EVP_VerifyInit_ex(ctx, EVP_sha1(), NULL);


//
// After initializing the context, the signed data to be verified
// is fed into context. This is done with EVP_VerifyUpdate() function
//
EVP_VerifyUpdate(ctx, msg, sizeof(msg));


//
// Performing the actual verification of the signature using
// EVP_VerifyFinal() function
//
ret = EVP_VerifyFinal(ctx, sigBuf, bytesRet, evpkey);
if (0 == ret)
{
    printf("Signature doesn't match\n\n");
} // if
else
{
    printf("Signature verified successfully\n\n");
}

printf("Press RETURN to quit!\n\n");


getchar();

return 0;

}

我得到的只是:

"Signature doesn't match"

我做错了什么?请帮助!

1 个答案:

答案 0 :(得分:0)

在我切换到使用公共证书(----- BEGIN CERTIFICATE -----)而不是公钥之前,我遇到了类似的问题。在尝试读取PEM_read_bio_X509中的证书时,我实际上失败了。

在大多数情况下,您的程序在发生错误后仍在继续。可能会看一下添加返回以在错误事件中杀死程序,可能会防止错误被忽视。