Как правильно использовать CipherOutputStream для шифрования и дешифрования журнала, созданного с помощью log4j (RollingFileAppender) - PullRequest
9 голосов
/ 07 июля 2011

У меня проблема с шифрованием / дешифрованием файла журнала, созданного RollingFileAppender log4j.Для шифрования я попытался расширить RollingFileAppender, просто назовите его EncryptedRollingFileAppender.Я переопределяю метод

setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)

и в основном использую CipherOutputStream и Base64OutputStream для шифрования и кодирования всего, что записано в выходной поток.Вот часть кода:

...
setImmediateFlush(true);

FileOutputStream ostream = null;
CipherOutputStream cstream = null;
Base64OutputStream b64stream = null;
try {        
    byte[] keyBytes = "1234123412341234".getBytes();  //example
    final byte[] ivBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
         0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; //example

    final SecretKey key = new SecretKeySpec(keyBytes, "AES");
    final IvParameterSpec IV = new IvParameterSpec(ivBytes);
    final Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key, IV);

    ostream = new FileOutputStream(fileName, true);
    b64stream = new Base64OutputStream(ostream);
    cstream = new CipherOutputStream(b64stream, cipher);

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

Writer cw = createWriter(cstream);
...

А затем я расшифровал файл с этим кодом:

private static void decryptFile(String filename) throws Exception {
    FileInputStream fis = null;
    BufferedReader br = new BufferedReader(new FileReader(filename));

    File file = new File(filename + "-decrypted");
    file.createNewFile();
    Writer out = new OutputStreamWriter(new FileOutputStream(filename + "-decrypted"), "UTF-8");

    String line = null;
    try {
         while (( line = br.readLine()) != null){
             line = decrypt(Base64.decodeBase64(line));
             out.write(line);
         }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (br != null) {
            br.close();
        }
        if (fis != null) {
            fis.close();
        }
        if (out != null) {
            out.close();
        }
    }
}

public static String decrypt(byte[] line) throws Exception {
    byte[] keyBytes = "1234123412341234".getBytes();
    final byte[] ivBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
                0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };

    final SecretKey secretkey = new SecretKeySpec(keyBytes, "AES");
    final IvParameterSpec IV = new IvParameterSpec(ivBytes);
    final Cipher decipher = Cipher.getInstance("AES/CFB8/NoPadding");
    decipher.init(Cipher.DECRYPT_MODE, secretkey, IV);
    final byte[] plainText = decipher.doFinal(line);

    return new String(plainText, "UTF-8").trim();
}

Это сработало, но только частично.Некоторые тексты в файле результатов были расшифрованы правильно, а некоторые другие - нет.Если вам интересно, это то, что я имею в виду под частичным:

07 Jul 11 13:13:13, DEBUG  MrBean.java:checkUserVal���̥V;��ƃ�˨�� - username: squall,password: 4GROmr95Qcf����v�M�7�y�5�@CGO09 ,active: true 

Я также попытался изменить алгоритм на «DESede», но он все еще был частично расшифрован.Затем я попытался использовать «CBC / PKCS5Padding» в обоих концах, но я получил исключение

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

Я предполагаю, что шифрование неправильно заполняет ввод, но мне интересно, почему ... потому что, когда я использую то же самоеалгоритмы шифрования и дешифрования без CipherOutputStream заполнение работало просто отлично.Кто-нибудь может помочь мне сделать это работает?Будем благодарны за любую помощь.

PS: Извините за мой английский, это не мой родной язык.

1 Ответ

3 голосов
/ 07 июля 2011

выглядит довольно хорошо. Вы сбрасываете / инициализируете объект шифра для каждого сообщения? Вы, вероятно, не хотите этого делать, но если вы это сделаете, вам нужно тщательно продумать структуру файла шифра, потому что расшифровщик должен знать, где находятся границы сообщения.

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