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

Я пытаюсь кодировать простой "тест" строки "назад" и "вперед".

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 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 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

}

Однако, хотя шифрование работает просто отлично (ALGORITHM - "RSA" ), при попытке расшифровать строку, которую я только что получил от шифрования "test", я получаю следующее исключение:

javax.crypto.IllegalBlockSizeException: данные не должны превышать 256 байт

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

Ответ 1

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

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

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

Ответ 2

Из здесь:

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

Ответ 3

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

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