Поведение Java rsa decrypt_mode - PullRequest
       50

Поведение Java rsa decrypt_mode

1 голос
/ 04 октября 2019

Я просто экспериментировал со следующим кодом, но я не понимаю, почему код ведет себя так, как он:

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.

Поскольку я использую открытый ключ для дешифрования и в асимметричной криптографии с открытым ключом, мы можем зашифровать с открытым ключом и расшифровать с закрытым ключом.

Может кто-нибудьобъяснить это и, надеюсь, подкрепить это документацией?

Ответы [ 2 ]

1 голос
/ 05 октября 2019

Если вы укажете NoPadding, вы получите модульное возведение в степень. Конечно, перед этим есть шаг для преобразования двоичного ввода в число, а затем снова кодирование из числа в двоичное. Достаточно забавно, что это верно как для шифрования, так и для дешифрования, поскольку эти операции довольно симметричны для RSA.

Единственное отличие состоит в том, что вы сначала используете открытый ключ для шифрования и закрытый ключ для расшифровки. Однако иногда вам приходится создавать собственную схему проверки . В этом случае необработанное модульное возведение в степень с открытым ключом приятно даст вам (обычно дополненный) результат. Итак, расшифровка с открытым ключом имеет некоторый смысл, даже если технически это не следует называть расшифровкой.

В целом, если ваш ввод имеет правильный размер, чем просто декодированиеввод числа, модульное шифрование (или дешифрование) и, наконец, кодирование результата, никогда не удастся. Таким образом, вы просто получаете вывод с тем же размером, что и модуль, то есть размер ключа в байтах. Это unpadding для RSA, который может потерпеть неудачу. Но ваш код будет работать только потому, что вы не выполняете никаких операций заполнения.

Конечно, если вы используете неправильный модуль и показатель степени, результат расшифровки не будет иметь никакого смысла;оно будет выглядеть как случайное число между 0 и модулем, использованным для последней операции.

0 голосов
/ 04 октября 2019

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

Броски: InvalidKeyException - если данный ключ не подходит для инициализации этого шифра, или требует параметры алгоритма, которые не могут быть определены из данного ключа, или если данный ключ имеетразмер ключа, который превышает максимально допустимый размер ключа (определенный из настроенных файлов политики юрисдикции).

RSA в режиме дешифрования требует экземпляра PrivateKey вместо PublicKey, и, следовательно, в случае 2 из вышеприведенного примера возникнет это исключение.

Если вам интересно, почему это не приводит к ошибке времени компиляции, PublicKey и PrivateKey расширяют класс ключей, и, следовательно, подпись Cipher.init (int, Key) удовлетворяется обоими вариантами кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...