2

我正在尝试使用公钥解密字符串以与哈希进行比较。代码如下

byte[] dectyptedText = null;
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
return dectyptedText;

上面的代码生成这样的字符串(base64encode)

MCEwCQYFKw4DAhoFAAQUy3qkZYgfRVo2Sv1F9bHa3pDs044=

哈希由以下代码生成

 byte[] key = stringToHash.getBytes();
 MessageDigest md = MessageDigest.getInstance("SHA-1");
 hash = md.digest(key);

上面的代码生成一个示例哈希,如下所示

y3qkZYgfRVo2Sv1F9bHa3pDs044 =

如果您注意到两者都有正确的哈希值,即y3qkZYgfRVo2Sv1F9bHa3pDs044 = 但解密代码会生成并预先添加一个额外的MCEwCQYFKw4DAhoFAAQU

不明白这个额外的东西是如何添加的以及为什么。

请有人对此有所了解吗?

谢谢

前置

4

2 回答 2

6

这就是 PKCS1 填充。该算法将 pkcs 填充附加到您的明文数据(即您的哈希)中,以防止一些基于重复加密的纯文本数据的攻击。这是一种随机化输入数据的方法。如果您使用相同的密钥重新加密相同的哈希,您将获得不同的 pkcs 标头数据(当然还有不同的密码块)。显然 pkcs 填充具有固定长度,因此您可以将其剥离以获取原始纯文本。

于 2013-09-25T08:22:07.880 回答
5

您不应使用它Cipher来创建或验证签名。相反,您应该使用Signature.getInstance("SHA1withRSA").

签名方案和加密方案是不同的,它们不一定相互兼容。对于初学者,它们使用不同的填充方法,这些填充方法是算法安全性的一部分。

Cipher即使您可以使用 Cipher 进行签名验证,也有可能您还没有完全验证签名,并且如果正在使用不同的实现,您自制的签名验证方案可能(并且可能会)失败用过的。

问题中的代码似乎使用 PKCS#1 v1.5 填充进行加密而不是生成签名,因此它可能不正确。

于 2013-09-25T10:10:38.557 回答