我查找了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方面没有输出任何错误或失败。