我只是在尝试下面的代码,但是我不明白为什么代码会像这样运行:
public class Test
{
public static void main(String args[]) throws Exception
{
CertificateFactory certificateFactory1 = CertificateFactory.getInstance("X.509");
X509Certificate certificate1 = (X509Certificate)certificateFactory1.generateCertificate(Test.class.getResourceAsStream("pub.cer"); //Loading ssl certificate
PublicKey pk1 = certificate1.getPublicKey();
Cipher cipher1 = Cipher.getInstance("RSA/ECB/NOPADDING");
cipher1.init(Cipher.ENCRYPT_MODE, pk1);
bytes[] encrypted = cipher1.doFinal("dummy".getBytes("UTF-8");
CertificateFactory certificateFactory2 = CertificateFactory.getInstance("X.509");
X509Certificate certificate2 = (X509Certificate)certificateFactory2.generateCertificate(Test.class.getResourceAsStream("pub.cer"); //Loading ssl certificate
PublicKey pk2 = certificate2.getPublicKey();
Cipher cipher2 = Cipher.getInstance("RSA/ECB/NOPADDING");
cipher2.init(Cipher.DECRYPT_MODE, pk2);
bytes[] decrypted = cipher2.doFinal(encrypted);
}
}
为什么byte[]
解密了,我却得到doFinal
的输出?我正在使用jdk1.8.0_192。
因为我使用公共密钥进行解密,并且在非对称公共密钥加密中,我们可以使用公共密钥进行加密,而可以使用私有密钥进行解密。
有人可以解释一下并希望通过文档进行备份吗?
NoPadding
,则基本上可以得到模幂。当然,在此之前,有一个步骤将二进制输入转换为数字,然后再将编码从数字转换为二进制。有趣的是,加密和解密都是如此,因为这些操作对于RSA而言是相当对称的。 唯一的区别是您首先使用公共密钥进行加密,并使用
私有密钥进行解密。但是,有时您必须创建自己的verification方案。在这种情况下,原始的模块化指数使用公钥将很好地给您(通常填充)结果。因此,使用decryption和公钥是有道理的,即使从技术上讲不应将其称为解密。
总而言之,如果您输入的大小不仅仅只是将输入解码为数字,则模块化加密(或解密)并最终对结果进行编码将从不
失败。因此,您只会得到与模数大小相同的输出,即密钥大小(以字节为单位)。 RSA的取消填充可能会失败。但是您的代码将只运行,因为您无需进行任何填充。当然,如果使用错误的模数和指数,则解密的结果将毫无意义;它看起来像是介于0和上一次操作所使用的模数之间的随机数。抛出:InvalidKeyException-如果给定密钥不适合初始化此密码,或者需要无法从给定密钥确定的算法参数,或者给定密钥的密钥大小超过最大允许密钥大小(由配置的管辖权策略文件确定) 。
RSA在解密模式下要求使用PrivateKey实例而不是PublicKey,因此,上例的情况2将引发此异常。
[如果您想知道为什么它不会产生编译时错误,PublicKey和PrivateKey都扩展了Key Class,因此,两种情况都满足了Cipher.init(int,Key)签名。