You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现SHA512withRSA签名验签失败求助:代码问题排查

问题根源分析

你的验签失败是签名代码的逻辑错误导致的,核心问题在于手动重复计算哈希摘要,破坏了签名算法的预期流程。

具体错误点

签名代码的问题

你在签名时先手动计算了SHA512摘要:

MessageDigest digest = MessageDigest.getInstance("SHA512", "BC");
byte[] newDigest = digest.digest(data);

然后将这个摘要传给signature.update(newDigest),但SHA512withRSA/PSS算法本身已经包含了「SHA512哈希 + RSA-PSS签名」的完整流程,不需要手动提前计算哈希。这会导致签名实际是对原始数据的哈希值再做哈希签名,而非对原始数据直接签名。

验签与签名的不匹配

验签时你直接传入原始payload的字节:

ver.update(payload.getBytes());

这相当于验签时用原始数据做哈希,而签名时用的是原始数据的哈希值做哈希,两边处理的输入完全不匹配,自然验签失败。

修正方案

修复签名代码

删除手动计算哈希的步骤,直接用原始数据data更新Signature对象:

public String generateSignature() throws NoSuchAlgorithmException,
    NoSuchProviderException, InvalidKeyException, SignatureException, UnrecoverableKeyException,
    KeyStoreException {

    KeyStore keystore = getPrivateKeystore(privateKeyPath, keystorePassword.toCharArray());
    PrivateKey privateKey = getPrivateKey(privateKeyAlias, privateKeyPassword.toCharArray(), keystore);

    Signature signature = Signature.getInstance("SHA512withRSA/PSS", "BC");
    signature.initSign(privateKey);
    // 直接用原始数据更新,算法会自动处理SHA512哈希
    signature.update(data);

    byte[] sign = signature.sign();
    return Base64.getEncoder().encodeToString(sign);
}

验签代码的注意事项

验签代码本身逻辑没问题,但需要确保:

  • payload.getBytes()使用的字符编码和签名时data的字符编码一致(比如统一用UTF-8),避免字节数组不一致
  • getPublicKey方法返回的是对应私钥的配对公钥,没有拿错密钥

额外提示

  • 不要用String.valueOf(sign)打印字节数组,这会输出乱码,无法用于调试,建议用Base64或十六进制编码打印
  • RSA-PSS算法建议指定明确参数(如盐长度),避免不同环境默认参数不一致导致验签失败,可在initSign和initVerify前添加:
// 签名时设置PSS参数
signature.setParameter(new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, 1));
// 验签时设置相同参数
ver.setParameter(new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, 1));

内容的提问来源于stack exchange,提问作者vaibhav1291

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:11:03