我尝试了一天以上,但仍然无法让它发挥作用。
我正在尝试使用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"
我做错了什么?请帮助!
答案 0 :(得分:0)
在我切换到使用公共证书(----- BEGIN CERTIFICATE -----)而不是公钥之前,我遇到了类似的问题。在尝试读取PEM_read_bio_X509中的证书时,我实际上失败了。
在大多数情况下,您的程序在发生错误后仍在继续。可能会看一下添加返回以在错误事件中杀死程序,可能会防止错误被忽视。