C++ 为什么在C+中使用OpenSSL+;生成与命令行不同的输出
我查找了一些OpenSSL的代码示例,以便使用SHA256对某些内容进行散列,并使用RSA密钥对其进行签名——我还需要将生成的字符串编码为十六进制。我使用此来源作为参考: 这是接受消息的更高级别的方法C++ 为什么在C+中使用OpenSSL+;生成与命令行不同的输出,c++,encryption,openssl,rsa,sha256,C++,Encryption,Openssl,Rsa,Sha256,我查找了一些OpenSSL的代码示例,以便使用SHA256对某些内容进行散列,并使用RSA密钥对其进行签名——我还需要将生成的字符串编码为十六进制。我使用此来源作为参考: 这是接受消息的更高级别的方法 std::string Sign(const std::string& key, const std::string& message, bool bPrivate) { RSA* rsa = CreateRSAFromString(key, isPrivate);
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;
}
<强>我想验证我的过程是否正确,因为输出十六进制结果时,命令行和C++之间的结果完全不同。具体来说,我尝试实现的等效命令如下:
dgst -sha256 -sign certifcate.pem -out signed.txt inputFile.json
如果我能确保OpenSSL方面的东西是正确的,那么我可以推断是我对十六进制的转换导致了这种差异。OpenSSL端没有输出错误或失败。在命令行中使用证书(即公钥)时,代码中似乎使用了私钥。为了生成signatutre,您还应该在命令行中使用私钥。还要注意,即使使用相同的数据和密钥,签名字节也可能完全不同。这取决于签名上应用的填充(例如,任何随机填充方案,如PSS填充)。@oliv很抱歉命名错误,certificate.pem实际上是一个私有证书。填充看起来很可疑,但在我的代码中应该在哪里管理填充?创建摘要和RSA对象的方法似乎没有允许我这样做的参数。命令行
dgst
命令确实可以使用-sigopt
更改签名填充方案。至少可以使用EVP_PKEY_CTX_set_rsa_padding,但我不知道您使用的函数是什么using@oliv有趣的是,当我输入一个没有新行字符和不必要的间距的文件时,我的代码输出的结果与命令行相同。事实上,如果我将内容压缩成一个没有冗余字符的字符串,那么输出是正确的。
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;
}
dgst -sha256 -sign certifcate.pem -out signed.txt inputFile.json