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

Java如何生成可通过openssl pkeyutl恢复数据的封装式RSA签名

可恢复原始数据的RSA签名Java实现

问题原因

你当前使用的SHA256withRSA属于带摘要的分离式签名,签名结果是RSA私钥加密后的「SHA256摘要值+摘要算法标识」结构,本身不包含原始业务数据,因此仅支持结合原始数据做完整性校验,无法通过公钥反解恢复原始内容。

实现方案

要支持openssl pkeyutl -verifyrecover命令恢复原始数据,需要使用无摘要的Raw RSA签名模式,直接对原始数据做PKCS#1 v1.5填充后用私钥签名,仅适用于数据长度小于RSA密钥长度-11字节的小数据场景(比如2048位RSA最大支持245字节内容)。

代码实现

import java.security.Signature;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateKey;

public class RSASignGenerator {
    public byte[] generateRecoverableSign(byte[] content, PrivateKey privateKey) throws Exception {
        // 计算当前密钥支持的最大可签名内容长度(密钥长度单位为位,转换为字节后减11字节填充开销)
        int keyBitLength = privateKey instanceof RSAPrivateKey ? 
            ((RSAPrivateKey) privateKey).getModulus().bitLength() : 2048;
        int maxContentLen = keyBitLength / 8 - 11;
        if (content.length > maxContentLen) {
            throw new IllegalArgumentException("内容长度超出最大限制,当前密钥最多支持" + maxContentLen + "字节");
        }
        // 使用无摘要RSA签名,底层自动处理PKCS#1 v1.5签名填充
        Signature signature = Signature.getInstance("NONEwithRSA");
        signature.initSign(privateKey);
        signature.update(content);
        return signature.sign();
    }
}

异常兼容

如果运行时报找不到NONEwithRSA算法的错误,可引入BouncyCastle安全依赖,替换算法名为NONEWITHRSAPKCS1V15即可。

效果验证

将生成的签名字节写入signature文件后,执行指定OpenSSL命令即可直接输出原始内容:

openssl pkeyutl -verifyrecover -pubin -inkey public.pem -in signature

注意事项

  • 该方案仅适用于短内容签名场景,长内容必须使用常规分离式签名
  • 若需要同时保留摘要防篡改能力,可自行将「摘要值+原始内容」拼接后再签名,恢复后自行校验摘要一致性即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:15:08