我已经使用 rsa 使用我的公钥-e(对应的私钥-d)加密了一条小消息。但是如果我用另一个私钥 d' 解密它,它会给出一个bad padding exception
.
它怎么知道我用错了钥匙?
3 回答
使用填充方案确实可以让解密者很好地了解他要么使用了错误的密钥,要么正在处理损坏的数据。
填充方案具有明确定义的明文最终字节集。如果您使用错误的密钥解密,则生成的“明文”基本上是随机垃圾,因此极不可能以有效的填充序列结束。
大多数 RSA 库默认使用PKCS#1 块类型 2填充来进行公钥加密。在这种情况下,数据必须至少比模数大小小 11 个字节,并且明文填充如下:
00 02 r 1 r 2 r 3 r 4 ... r M ... 00 [你的明文字节]
其中 M >= 8 和 ri是随机正字节:它们都是非零的。
这是将模数提高到 e次方的实际值。因此,解密后解密器可以检查结果是否如下所示,即
- 高位字节为 0
- 高位字节的下一个是 2
- 至少接下来的 8 个字节非零
- 在此之后某处出现零字节
该机制实际上很简单,因为它很聪明。
想象一个对 8 个字节的块进行加密的分组密码:它将每个明文消息分成 8 个字节的组,并将每个组加密为单个块。说到最后一个区块,有两种可能:
该块短于 8 个字节,并且必须填充到正好 8 个字节。在这种情况下,必须将一些字节数n附加到块中。这些字节中的每一个都具有相同的二进制值n。所以最后一个块看起来像其中一个,其中
d
是一个字节的数据:dddddd 1 dddddd
2 2
ddddd 3 3 3
。. .
d 7 7 7 7 7 7 7该块正好是 8 个字节长。在这种情况下,整个块被附加到消息中,所以最后 2 个块看起来像这样:
dddddddd 8 8 8 8 8 8 8 8
现在,当消息被解密时,解密器可以明确地知道要删除多少字节的填充。如果最后一个块不以n
字符结尾,每个字符都带有二进制值n
,它就知道消息已被破坏或使用错误的密钥解密。
不要将此填充与用于修改消息开头的初始化向量或 IV 混淆。填充的目的是确保消息只包含完整的块,并允许解密器验证密钥。IV 是一个随机的字节序列,确保相同的明文可以使用相同的密钥多次加密,但每次仍生成不同的密文。