Java rsa decrypt_mode 行为

Java rsa decrypt_mode behavior

我只是在试验以下代码,但我不明白为什么代码会这样运行:

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.

因为我使用 public 密钥进行解密,在非对称 public 密钥加密中,我们可以使用 public 密钥加密并使用私钥解密。

有人可以解释一下并希望用文档来支持它吗?

https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html#init(int,%20java.security.Key)

Throws: InvalidKeyException - if the given key is inappropriate for initializing this cipher, or requires algorithm parameters that cannot be determined from the given key, or if the given key has a keysize that exceeds the maximum allowable keysize (as determined from the configured jurisdiction policy files).

解密模式下的 RSA 需要 PrivateKey 实例而不是 PublicKey,因此上述示例的情况 2 会抛出此异常。

如果您想知道为什么它不会产生编译时错误,PublicKey 和 PrivateKey 都扩展了 Key Class 因此 Cipher.init(int,Key) 签名满足两种情况你的代码。

如果你指定 NoPadding 那么你基本上得到模幂。当然,在此之前还有一个将二进制输入转换为数字的步骤,然后再将数字编码为二进制。有趣的是,加密和解密都是如此,因为这些操作对于 RSA 来说是相当对称的。

唯一的区别是您首先使用 public 密钥进行加密,然后使用 私钥 进行解密。但是,有时您必须创建自己的 验证 方案。在那种情况下,使用 public 键 的原始模幂 将很好地为您提供(通常填充的)结果。因此,使用 public 密钥进行 解密 是有一定意义的,即使从技术上讲它不应该被称为解密。

总而言之,如果您的输入大小合适,而不只是将输入解码为数字,模块化加密(或解密)和最终编码结果将 永远不会失败。所以你只得到一个与模数大小相同的输出,即以字节为单位的密钥大小。 RSA 的 unpadding 可能会失败。但是你的代码只会 运行 因为你没有做任何 unpadding。

当然,如果你用错了模数和指数,解密的结果将毫无意义;它看起来像是一个介于 0 和上次操作所用模数之间的随机数。

这些入侵我的 phone 的人在上面使用了这种方法,导致它没有被加密..(除其他外)我的 phone 不会更新,就好像它植根于他们的计算机..