首页 > 解决方案 > 如何使用相应的 X509 证书验证私有 RSA 签名签名

问题描述

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

openssl req -x509 -newkey rsa:1024 -keyout key.pem -out certificate.pem -days 730 -nodes

现在在 C++ 中,我想用私钥 SHA1 对一些数据进行签名,然后使用证书验证签名:RSA_sign vs RSA_verify

这是我运行的完整代码(省略了错误案例):

#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;
}

验证结果为FALSE

ERR_get_error()返回67702888

我究竟做错了什么?

标签: c++linuxsslopenssl

解决方案


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


推荐阅读