自定义RSA数字签名输出512字节是否正常?技术问询
问题解答:这是代码逻辑的必然结果,不是bug,但实现完全不符合RSA签名规范
为什么会得到512字节签名?
这是你代码执行后的必然结果,不是程序bug:
- SHA-512哈希的长度为64字节,你的代码把哈希的每个字节单独作为消息做一次RSA签名;
- 你生成的RSA密钥对中,P和Q都是32位素数,模数N为64位(对应8字节),每个签名结果被转成8字节输出(由
toHH方法处理); - 64个哈希字节 × 每个字节对应8字节签名 = 512字节,完全匹配你代码的执行逻辑。
但你的实现存在多处严重问题,完全不符合标准
1. 拆分哈希字节签名的逻辑错误
标准RSA签名是将整个哈希值(或经过标准填充后的哈希)作为一个整体进行签名,而非拆分单个字节处理。这种做法的问题:
- 签名长度冗余且无意义;
- 安全性极低,每个字节的签名都是独立的小消息,极易被破解或篡改。
2. 密钥强度完全不足
32位素数生成的模数N仅64位,现代计算机可瞬间破解此类密钥,完全起不到安全防护作用。当前标准RSA密钥至少需要2048位,推荐使用4096位。
3. 签名与验证的密钥完全搞反
RSA签名的核心逻辑是:
- 签名:用私钥(你代码中的
d)对消息执行模幂运算; - 验证:用公钥(你代码中的
c,即d的逆元)对签名结果执行模幂运算,得到原始消息后对比。
但你代码中是用公钥c签名、私钥d验证,这本质是公钥加密而非私钥签名,完全失去了签名的不可否认性。
4. 验证逻辑失效
你的验证代码只要有一个字节匹配就返回true,这意味着即使图片被大面积篡改,只要有一个字节未变动就会被判定验证通过,完全失去了签名防篡改的意义。正确逻辑是所有字节匹配才能返回验证通过。
正确的RSA签名实现思路
- 生成2048位及以上长度的RSA密钥对;
- 对SHA-512哈希值应用标准填充方案(如PKCS#1 v1.5或PSS填充,这是必要步骤,避免直接对哈希签名带来的安全漏洞);
- 使用私钥对填充后的完整哈希值执行模幂运算,得到单个签名结果;
- 验证时用公钥对签名结果执行模幂运算,去除填充后与重新计算的哈希值对比,全部匹配则验证通过。
内容的提问来源于stack exchange,提问作者Rume Diablo
相关产品推荐
相关产品推荐

