我使用以下方法在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();
然后我将结果作为Hex String保存到文本文件中,并使用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获得的十六进制,但我不知道什么是exaclty。
更新
使用Pras建议的摘要后,我在使用ERR_get_error时收到此消息错误:
error:04091068:rsa routines:INT_RSA_VERIFY:bad signature
答案 0 :(得分:1)
来自RSA_verify()手册页:
RSA_verify()验证siglen大小的签名sigbuf是否匹配 给定的消息摘要m,大小为m_len。 type表示消息 用于生成签名的摘要算法。 rsa是 签名者的公钥。
所以第二个和第三个参数应该是消息摘要和摘要长度而不是实际的消息和签名的消息长度
答案 1 :(得分:0)
可能byte[] data = message.getBytes();
可能不会提供与message.c_str()
相同的字节序列。我建议你用调试器检查一下。