Шифрование и дешифрование фрагмента текста в Java с помощью JCA и JCE - PullRequest
0 голосов
/ 26 декабря 2011

Я пытаюсь написать простое приложение для шифрования и дешифрования фрагмента текста, используя JCA и JCE из Java.

Пока часть шифрования работает, но она дает мне следующее исключениепри расшифровке:

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher

Это часть, где я инициализирую два шифра, encCipher и decCipher.

PBEKeySpec pbeKeySpec;
PBEParameterSpec paramSpec;
SecretKeyFactory keyFac;
byte[] salt = {(byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
               (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99};
int count = 20;
paramSpec = new PBEParameterSpec(salt, count);

try {
    pbeKeySpec = new PBEKeySpec("my_password".toCharArray(), salt, count);
    SecretKey secretKey = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(pbeKeySpec);

    encCipher = Cipher.getInstance(secretKey.getAlgorithm());
    encCipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
    decCipher = Cipher.getInstance(secretKey.getAlgorithm());
    decCipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);

} catch (Exception ex) {
    ex.printStackTrace();
 }

У меня нет опыта использования архитектуры криптографии Java, я хотел бы знать, как можно исправить ошибку.

Исключение происходит в строке с decCipher.doFinalот loadClients.

private void saveClients() {
   String plainText = "";
   String encText = "";
   Set<String> clients = my_clients.keySet();
        try {
            PrintWriter out = new PrintWriter(new File(output_file));
            for (String client : clients) {
                long client_time = my_clients.get(client);
                plainText = client + " " + client_time;

                encText = new String(encCipher.doFinal(plainText.getBytes()));
                out.println(encText);
            }
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void loadClients() {
        BufferedReader in;
        String line;
        try {
            in = new BufferedReader(new FileReader(output_file));
            while ((line = in.readLine()) != null) {
                byte[] decBytes = decCipher.doFinal(line.getBytes());
                String decText = new String(decBytes);
                String[] client_data = decText.split("[ ]");
                my_clients.put(client_data[0], Long.parseLong(client_data[1]));
            }
            in.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
     }

1 Ответ

1 голос
/ 26 декабря 2011

Проблема заключается в том, что вы преобразовываете байты в строки.Предположим, что вашей кодировкой платформы по умолчанию является ASCII.Это означает, что половина байтов, содержащихся в вашем зашифрованном тексте (байты 128 и выше), не представляют допустимые символы.Кроме того, вы пишете одну строку для каждого зашифрованного текста.Итак, если ваш зашифрованный байтовый массив содержит символ новой строки, вы на самом деле напишите автору две строки и попытаетесь расшифровать каждую строку одну за другой, что приведет к исключению.

Любое использованиебайты для хранения и передачи ваших зашифрованных данных или преобразования их в строки с использованием алгоритма без потерь, например Base64 (который гарантирует, что все будет преобразовано в печатные символы).Apache commons-codec имеет реализацию Base64.

...