#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. Да, я неправильно истолковал ваш вопрос, но я думаю, что в любом случае это хороший совет на будущее. Удачи!