RSA_verify,can'中预期的数据类型是什么;t验证从Java生成的签名

RSA_verify,can'中预期的数据类型是什么;t验证从Java生成的签名,java,c++,openssl,digital-signature,Java,C++,Openssl,Digital Signature,我使用以下方法在Java上创建签名: String message = "my message"; byte[] data = message.getBytes(); byte[] result; Signature sig = Signature.getInstance("SHA512withRSA"); sig.initSign(this.privateKey); sig.update(data); result = sig.sign(); 然后,我将结果作为十六进制字符串保存到文本文件中

我使用以下方法在Java上创建签名:

String message = "my message";
byte[] data = message.getBytes();
byte[] result;
Signature sig = Signature.getInstance("SHA512withRSA");
sig.initSign(this.privateKey);
sig.update(data);
result = sig.sign();
然后,我将结果作为十六进制字符串保存到文本文件中,并使用openssl尝试验证:

string signature//read hex string in the text file 
string message = "my message";
RSA *rsaPkey = NULL;

FILE *pemFile;
fopen_s(&pemFile, publicKeyFile, "r");
rsaPkey = PEM_read_RSA_PUBKEY(pemFile, &rsaPkey, NULL, NULL);
fclose(pemFile);

if(rsaPkey == NULL)
{
    RSA_free(rsaPkey);
    return 0;
}

int type                = NID_sha512;
const char *m           = message.c_str();
unsigned int m_len      = message.length();
int size                = RSA_size(rsaPkey);
unsigned char *sigret   = (unsigned char*) signature.c_str();
unsigned int siglen     = signature.length();

unsigned char digest[SHA512_DIGEST_LENGTH];

SHA512_CTX ctx;
SHA512_Init(&ctx);
SHA512_Update(&ctx, m, m_len);
SHA512_Final(digest, &ctx);

int r = RSA_verify(type, digest, SHA512_DIGEST_LENGTH, sigret, siglen, rsaPkey);
r
始终为0,表示验证失败。我认为这是因为它期望消息或签名的格式比我从Java获得的十六进制格式更为特殊,但我不知道具体是什么

更新

按照Pras的建议使用摘要后,当我使用ERR_get_error时,我收到以下消息错误:
错误:04091068:rsa例程:INT\u rsa\u验证:错误签名

可能是
byte[]data=message.getBytes()
可能不会给出与
message.c_str()
相同的字节序列。我建议您使用调试器进行检查。

从RSA_verify()手册页:

RSA_verify()验证siglen大小的签名sigbuf是否匹配 大小为m_len的给定消息摘要m。类型表示消息 用于生成签名的摘要算法。rsa是 签名者的公钥


所以第二个和第三个参数应该是消息摘要和摘要长度,而不是实际的消息和签名的消息长度

它们是相同的。你很幸运。您应该使用长格式,指定字符集。您是对的,我刚刚尝试使用摘要,但仍然得到0。我更新了问题也许我还遗漏了什么