java - RSA_verify中预期的数据类型是什么,无法验证从Java生成的签名

标签 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();


然后,将结果作为十六进制字符串保存到文本文件中,并使用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时出现此消息错误:
error:04091068:rsa routines:INT_RSA_VERIFY:bad signature

最佳答案

从RSA_verify()手册页:


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


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

关于java - RSA_verify中预期的数据类型是什么,无法验证从Java生成的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50700226/

相关文章:

Java 8 - 使用 startsWith 从列表中过滤字符串 X 并将字符串 X 保存到列表

java - 使用 Java 8 连接集合

c++ - 重叠字符串

c++ - std::ofstream 二进制写入的意外结果

openssl - 在 Contiki 中使用 OpenSSL

c# - 等效于openssl中的PasswordDeriveBytes

java - 使用 StringBuilder 生成逗号分隔列表

java - 类型转换与使用 valueOf

c++ - Direct3D 是否应该用于 Windows 中的 OpenGL?

ios - 一个函数可以快速给出几个结果