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

Java使用RSA公钥通过Signature验证数据始终返回false的原因及解决方案

返回false的根本原因

你的代码从运算逻辑、填充规则、接口用法三个层面都存在错误,所以永远返回false:

  • 混淆了RSA公钥加密和RSA数字签名的核心逻辑:
    RSA加密的作用是保证数据保密性,用公钥加密明文,运算后得到的是只能用私钥解密的密文;而SHA256withRSA签名的作用是做身份校验和完整性校验,生成签名时是用私钥对「明文的SHA256哈希值+签名专用填充标识」做运算,验证时用公钥把签名解密得到哈希值,再和本地计算的明文哈希对比是否一致。你现在把公钥加密得到的密文直接当做签名传给verify方法,签名类解密后得到的是原明文"a",和预期的SHA256哈希结构完全不匹配,自然校验失败。
  • 填充规则不兼容:你调用Cipher.getInstance("RSA")用的是JDK默认的加密类PKCS#1填充,和SHA256withRSA用的签名专用PKCS#1 v1.5填充格式完全不同,就算内容一致,填充部分也会导致校验失败。
  • 接口用法错误:Signature类的verify方法接收的是sign()方法生成的签名字节数组,不是Cipher类加密输出的密文字节数组,二者不能混用。

正确的实现方式

根据你的实际业务需求,选择对应方案即可:

场景1:校验RSA加密结果的正确性

如果只是要确认加密后的密文可以正常还原为原明文,不需要用Signature类,直接用私钥解密密文后和原明文对比即可:

import java.util.Arrays;
// 省略原有密钥生成、明文定义、加密逻辑
// 新增解密校验逻辑
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 显式指定填充规则避免跨环境兼容问题
decryptCipher.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte[] decryptedText = decryptCipher.doFinal(encryptText);
boolean result = Arrays.equals(plaintext, decryptedText);
System.out.println(result); // 输出true

场景2:需要做数字签名验证

如果确实要实现签名校验能力,不要用Cipher加密的结果当签名,而是用私钥生成标准签名后再校验:

// 1. 私钥生成签名
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(kp.getPrivate());
sig.update(plaintext);
byte[] signature = sig.sign(); // 此处输出的才是合法签名字节数组

// 2. 公钥验证签名
sig.initVerify(kp.getPublic());
sig.update(plaintext);
boolean result = sig.verify(signature);
System.out.println(result); // 输出true

内容的提问来源于stack exchange,提问作者An Dương

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:24:07