首页 > 解决方案 > 为什么 C++ 中的 OpenSSL 产生与命令行不同的输出

问题描述

我查找了一些 OpenSSL 的代码示例,以便使用 SHA256 对一些内容进行哈希处理并使用 RSA 密钥对其进行签名——我还需要将生成的字符串编码为十六进制。我将此来源用作参考:https ://gist.github.com/irbull/08339ddcd5686f509e9826964b17bb59

这是接受消息的更高级别的方法

std::string Sign(const std::string& key, const 
std::string& message, bool bPrivate)
{


    RSA* rsa = CreateRSAFromString(key, isPrivate);

    if(!rsa)
    {
        // Print errors here...
        return "";
    }

    unsigned char* outMessage;           
    size_t outMessageLength;

    RSASign(rsa, 
            (unsigned char*) message.c_str(), 
            message.length(), 
            &outMessage, 
            &outMessageLength);


    std::string myString(reinterpret_cast<const char*>(outMessage), outMessageLength);

    // Convert the string to hex
    std::string hexOutMessage = ToHex(myString);
    free(outMessage);
    return hexOutMessage;
}

实际的 RSA 签名方法看起来非常简单。据我了解,这应该首先使用 SHA256 对内容进行哈希处理,然后再使用 RSA 进行加密。

bool RSASign(RSA* rsa,
        const unsigned char* msg,
        size_t msgLength,
        unsigned char** outMsg,
        size_t* outMsgLength)
{ 
EVP_MD_CTX* context = EVP_MD_CTX_create();

EVP_PKEY* privateKey = EVP_PKEY_new(); 
EVP_PKEY_assign_RSA(privateKey, rsa);  


if(EVP_DigestSignInit(context, NULL, EVP_sha256(), NULL, privateKey) <= 0)
{
    return false;   // Initialize the digest failed
}

if (EVP_DigestSignUpdate(context, msg, msgLength) <= 0) 
{
    return false;   // Adding the message failed
}

if (EVP_DigestSignFinal(context, NULL, outMsgLength) <= 0)
{
    return false;   // Finalization failed, cannot create signature
}

*outMsg = (unsigned char*)malloc(*outMsgLength);
if(EVP_DigestSignFinal(context, *outMsg, outMsgLength) <= 0)
{
    return false;   // Error creating encoded message
}
EVP_MD_CTX_destroy(context);
// End of context

return true;
}

为了完整起见,这是实际创建 RSA 对象的地方:

RSA* CreateRSAFromString(const std::string& key, bool isPrivate)
{
RSA* rsa = NULL;
BIO* keybio = BIO_new_mem_buf((void*)key.c_str(), -1);  

if(!keybio)
{
    return NULL;
}

rsa = isPrivate ? PEM_read_bio_RSAPrivateKey(keybio, NULL, NULL, NULL):
                  PEM_read_bio_RSA_PUBKEY(keybio, NULL,NULL, NULL);
return rsa;
}

我想验证我的过程是否正确,因为在输出十六进制结果时,我在命令行和 C++ 之间得到完全不同的结果。具体来说,我试图实现的等效命令如下:

dgst -sha256 -sign certifcate.pem -out signed.txt inputFile.json

如果我可以确保事物的 OpenSSL 方面是正确的,那么我可能会推断出是我转换为十六进制导致了差异。在 OpenSSL 方面没有输出任何错误或故障。

标签: c++encryptionopensslrsasha256

解决方案


推荐阅读