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

Verify SHA-1 signature using OpenSSL with Visual Studio

本文关键字:OpenSSL 验证 SHA-1 签名 Visual Studio      更新时间:2023-10-16

我试了一天多,但仍然无法实现。

我正在尝试使用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 filenn");
}

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

//
// 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 : %snn", 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 objectn");
} // if
else
{
    printf("Memory allocated for EVP_MD_CTX objectnn");
}

//
// 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 matchnn");
} // if
else
{
    printf("Signature verified successfullynn");
}
printf("Press RETURN to quit!nn");

getchar();
return 0;
}

我得到的只是:

"Signature doesn't match"

我做错了什么?请帮忙!

我也遇到了类似的问题,直到我改用公共证书(-----BEGIN certificate-----)而不是公钥。我的在尝试读取PEM_read_bio_X509中的证书时实际上失败了。

在大多数情况下,您的程序似乎在发生错误后仍在继续。可能会考虑在错误事件中添加返回来杀死程序,可能会防止错误在未被注意的情况下溜走。