Шифрование Java RSA

#java #encryption #rsa #long-integer

#java #шифрование #rsa #длинное целое число

Вопрос:

Я пытаюсь закодировать простую строку «test» взад и вперед.

 public static String encode(Key publicKey, String data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

    byte[] byteData = data.getBytes(); // convert string to byte array

    Cipher cipher = Cipher.getInstance(ALGORITHM); // create conversion processing object
    cipher.init(Cipher.ENCRYPT_MODE, publicKey); // initialize object's mode and key

    byte[] encryptedByteData = cipher.doFinal(byteData); // use object for encryption

    return new String(encryptedByteData); // convert encrypted byte array to string and return it

}

public static String decode(Key privateKey, String data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

    byte[] byteData = data.getBytes(); // convert string to byte array

    Cipher cipher = Cipher.getInstance(ALGORITHM); // create conversion processing object
    cipher.init(Cipher.DECRYPT_MODE, privateKey); // initialize object's mode and key

    System.out.println(byteData.length);

    byte[] decryptedByteData = cipher.doFinal(byteData); // use object for decryption

    return new String(decryptedByteData); // convert decrypted byte array to string and return it

}
  

Однако, хотя шифрование работает просто отлично (АЛГОРИТМ «RSA»), при попытке расшифровать строку, которую я только что получил в результате шифрования «test», я получаю следующее исключение:

javax.crypto.Исключение IllegalBlockSizeException: данные не должны быть длиннее 256 байт

Должен ли я разделить зашифрованные байты на куски по 256, чтобы иметь возможность их расшифровать?

Ответ №1:

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

Измените свой код, чтобы вместо него использовать byte[] (результат метода ‘doFinal()`.

Если вам нужно преобразовать byte[] в символьную строку, используйте кодировку типа Base-64.

Комментарии:

1. Ах, отлично, спасибо, работает отлично! Да, я предполагаю, что повреждение происходит, когда я преобразую зашифрованный массив байтов в строку.

Ответ №2:

Отсюда:

Алгоритм RSA может шифровать только те данные, максимальная длина байта которых равна длине ключа RSA в битах, разделенных на восемь минус одиннадцать байтов заполнения, т. е. максимальное количество байтов = длина ключа в битах / 8-11. Если вы хотите зашифровать большие данные, то используйте ключ большего размера, например, ключ с 4096 битами позволит вам зашифровать 501 байт данных.

Комментарии:

1. Хотя я прочитал предложение в той же формулировке, что и в результатах поиска Google, установка ключа выше у меня не сработала. Я протестировал длину массива байт шифрования и заметил, что при увеличении длины ключа с 2048 до 4096 увеличилась и длина массива байт, ни в том, ни в другом случае она не подходила, в обоих случаях я получил исключение.

Ответ №3:

Если у вас есть длинные данные, вы должны либо разделить их на подходящие фрагменты данных и зашифровать / расшифровать каждый из них (не такая уж хорошая идея), либо зашифровать / расшифровать их с помощью симметричного алгоритма (AES / DES / RC4 / etc.), зашифровать симметричный ключ с помощью открытого ключа RSA и отправить оба на другую сторону. (гораздо лучшая идея).

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

Комментарии:

1. Спасибо. Я сделаю это, когда данные действительно превысят лимит, но проблема заключалась не в этом при шифровании такой простой строки, как «test».

2. Да, я неправильно истолковал ваш вопрос, но я думаю, что в любом случае это хороший совет на будущее. Удачи!