使用DECRYPT_MODE的RSA/ECB/PKCS1Padding

Pre*_*air 1 encryption hash sha1 rsa pkcs#1

我试图用公钥解密字符串以与哈希进行比较.代码是关注的

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

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

MCEwCQYFKw4DAhoFAAQUy3qkZYgfRVo2Sv1F9bHa3pDs044 =

哈希由以下代码生成

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

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

y3qkZYgfRVo2Sv1F9bHa3pDs044 =

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

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

请问有人对此有所了解吗?

谢谢

Gia*_*ini 5

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


Maa*_*wes 5

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

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

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

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