C++ 如何使用相应的X509证书验证私有RSA签名

C++ 如何使用相应的X509证书验证私有RSA签名,c++,linux,ssl,openssl,C++,Linux,Ssl,Openssl,我已在linux上使用此命令生成了私钥-证书对: openssl req -x509 -newkey rsa:1024 -keyout key.pem -out certificate.pem -days 730 -nodes 在C++中,我想用私钥Sa1来签署一些数据,然后用证书验证签名: RSAIONGNOS/ VS> StRealSuxRealSuff> >/P> 以下是我运行的完整代码(错误案例省略): #include <openssl/err.h> #include

我已在linux上使用此命令生成了私钥-证书对:

openssl req -x509 -newkey rsa:1024 -keyout key.pem -out certificate.pem -days 730 -nodes
在C++中,我想用私钥Sa1来签署一些数据,然后用证书验证签名:<强> RSAIONGNOS/<强> VS> StRealSuxRealSuff> <强> >/P> 以下是我运行的完整代码(错误案例省略):

#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/pem.h>
#include <QByteArray>
#include <QString>

QByteArray sign(const QString& data)
{
    FILE * key_fd = NULL;
    EVP_PKEY * key = NULL;
    unsigned char * msg_to_sign = NULL;

    QString key_file = "key.pem";
    key_fd = fopen(key_file.toLatin1().data(), "rt");

    key = PEM_read_PrivateKey(key_fd, NULL, NULL, NULL);

    int data_len = data.size();
    msg_to_sign = new unsigned char[data_len];
    memcpy(msg_to_sign, data.toUtf8().constData(), data_len);

    unsigned char msg_to_sign_sha1[SHA_DIGEST_LENGTH];

    SHA1(msg_to_sign, data_len, msg_to_sign_sha1))

    unsigned char signed_msg_hash[KEY_LENGTH_IN_BITS] = {0};
    unsigned int signed_msg_hash_length = 0;
    int ret = RSA_sign(NID_sha1,
                       msg_to_sign_sha1, SHA_DIGEST_LENGTH,
                       signed_msg_hash, &signed_msg_hash_length,
                       key->pkey.rsa);

    QByteArray ba;
    ba.append((char *) signed_msg_hash);
    return ba;
}

bool verify(QString& data, QByteArray& signature)
{
    FILE * certificate_fd = NULL;
    unsigned char * msg_to_verify = NULL;
    unsigned char * msg_signature = NULL;

    QString cert_file("certificate.pem");
    certificate_fd = fopen(cert_file.toLatin1().data(), "rt");

    X509 * cert = PEM_read_X509(certificate_fd, NULL, NULL, NULL);

    EVP_PKEY * evp_pubkey;
    evp_pubkey  = X509_get_pubkey(cert);

    RSA * rsa_pubkey;
    rsa_pubkey  = EVP_PKEY_get1_RSA(evp_pubkey);

    int signature_len = signature.size();
    msg_signature = new unsigned char[signature_len];
    memcpy(msg_signature, signature.constData(), signature_len);

    int data_len = data.toUtf8().size();
    msg_to_verify = new unsigned char[data_len];
    memcpy(msg_to_verify, data.toUtf8().constData(), data_len);

    int RESULT = RSA_verify(NID_sha1, msg_to_verify, data_len, msg_signature, 
    signature_len, rsa_pubkey);

    return RESULT == 1;
}


int main()
{
    QString dataToSign("a");
    QByteArray signature = sign(dataToSign);

    bool result =  verify(dataToSign, signature);
    // RESULT is FALSE

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
QByteArray符号(常量字符串和数据)
{
文件*key_fd=NULL;
EVP_PKEY*key=NULL;
无符号字符*msg_to_sign=NULL;
QString key_file=“key.pem”;
key_fd=fopen(key_file.toLatin1().data(),“rt”);
key=PEM\u read\u PrivateKey(key\u fd,NULL,NULL);
int data_len=data.size();
msg_to_sign=新的无符号字符[data_len];
memcpy(msg_to_sign,data.toUtf8().constData(),data_len);
无符号字符msg_to_sign_sha1[SHA_DIGEST_LENGTH];
SHA1(信号至符号、数据、信号至符号)
无符号字符有符号\u msg\u散列[KEY\u LENGTH\u IN\u BITS]={0};
无符号整数有符号\u msg\u hash\u长度=0;
int-ret=RSA_符号(NID_sha1,
消息到符号,符号长度,
带符号的\u msg\u散列,&带符号的\u msg\u散列长度,
密钥->pkey.rsa);
QByteArray ba;
ba.追加((字符*)有符号\u msg\u散列);
返回ba;
}
bool验证(字符串和数据、QByteArray和签名)
{
文件*证书\u fd=NULL;
无符号字符*msg\u to\u verify=NULL;
无符号字符*msg_signature=NULL;
QString证书文件(“certificate.pem”);
certificate_fd=fopen(cert_file.toLatin1().data(),“rt”);
X509*证书=PEM\U read\U X509(证书\U fd,空,空,空);
执行副总裁*执行副总裁;
evp_pubkey=X509_get_pubkey(证书);
RSA*RSA_公钥;
rsa_pubkey=EVP_PKEY_get1_rsa(EVP_pubkey);
int signature_len=signature.size();
msg_signature=新的未签名字符[signature_len];
memcpy(msg_签名,signature.constData(),signature_len);
int data_len=data.toUtf8().size();
msg_to_verify=新的无符号字符[data_len];
memcpy(msg_to_verify,data.toUtf8().constData(),data_len);
int RESULT=RSA\u verify(NID\u sha1,msg\u to\u verify,data\u len,msg\u签名,
签名(包括rsa公开密钥);
返回结果==1;
}
int main()
{
QString dataToSign(“a”);
QByteArray签名=签名(dataToSign);
bool结果=验证(数据签名、签名);
//结果是假的
返回0;
}
验证的结果为

ERR\u get\u error()返回67702888


我做错了什么?

我在签署msg-SHA1并只验证msg。当它们一致时,现在就可以了。

我签署了msg-SHA1,只验证了msg。当它们一致时,现在就可以了