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

如何分两步生成与直接调用SHA256withRSA结果一致的RSA数字签名

问题解答

签名结果不一致的原因及修复

你手动签名和自动签名结果不同的核心原因是:SHA256withRSA 底层并不是直接对原始哈希值做RSA运算,而是会先将哈希值封装为符合PKCS#1 v1.5规范的DigestInfo DER编码结构,再对这个结构做签名,你之前的手动步骤缺失了封装DigestInfo的环节。

DigestInfo结构包含了哈希算法的OID标识和哈希值本身,针对SHA256算法,这个结构的前缀是固定的,你只需要手动拼接前缀和原始哈希值,再做NONEwithRSA签名即可得到和自动签名完全一致的结果。

修复代码示例

首先定义SHA256对应的固定前缀:

// SHA256对应的DigestInfo DER编码固定前缀
private static final byte[] SHA256_DIGEST_INFO_PREFIX = new byte[] {
    0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, (byte)0x86, 0x48, 
    0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};

修改主类中手动签名的逻辑,拼接前缀和哈希值后再签名:

//MANUALLY SIGN & VERIFY
System.out.println("\nMANUALLY SIGN & VERIFY");
byte[] manualHashBytes = ManualHash.hash("SHA-256", dataBytes);
// 拼接DigestInfo前缀和原始哈希值
byte[] digestInfoBytes = ByteBuffer.allocate(SHA256_DIGEST_INFO_PREFIX.length + manualHashBytes.length)
        .put(SHA256_DIGEST_INFO_PREFIX)
        .put(manualHashBytes)
        .array();
// 对DigestInfo结构做签名
byte[] manualSignatureBytes = ManualHash.sign("NONEwithRSA", privateKey, digestInfoBytes);

额外问题解答

数字签名是基于原始二进制哈希值计算的,Base64只是将二进制哈希值转换为可读文本的编码方式,不会参与实际的签名运算,如果你传入Base64编码后的字节做签名,得到的结果会是错误的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:09:03