本文介绍了如何正确使用CipherOutputStream加密和解密使用log4j创建的日志(RollingFileAppender)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在加密/解密log4j的RollingFileAppender生成的日志文件时遇到问题。对于加密,我试图扩展RollingFileAppender,只需将其称为EncryptedRollingFileAppender。我覆盖方法

I have a problem in encrypting/decrypting log file generated by log4j's RollingFileAppender. For the encryption I have tried to extend the RollingFileAppender, just call it EncryptedRollingFileAppender. I override the method

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

,基本上我使用CipherOutputStream和Base64OutputStream加密和编码写入输出流的所有内容。这是代码的一部分:

and basically I use CipherOutputStream and Base64OutputStream to encrypt and encode everything written to the output stream. Here's part of the code:

...
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);
...

然后我用这段代码解密文件:

And then i decrypt the file with this code:

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();
}

它只是部分工作。结果文件中的一些文本被正确解密,但其他文本没有被解密。如果你好奇,这是我的意思部分:

It worked but only partially. Some texts in the result file were decrypted correctly but some others were not. If you're curious, this is what I mean by partially:

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,但是我有一个例外

I also have tried changing the algorithm to "DESede" but it was still partially decrypted. Then I tried to use "CBC/PKCS5Padding" in both ends but I got an exception

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

我假设加密没有正确填充输入,我不知道为什么...因为当我使用相同的加密和解密算法没有CipherOutputStream的填充工作很好。
任何人都可以帮我做这个工作吗?任何帮助将不胜感激。

I assume the encryption is not properly padding the input but I wonder why... because when I use the same encryption and decryption algorithms without the CipherOutputStream the padding worked just fine.Anyone can help me to make this works? Any help will be appreciated.

PS:抱歉我的英语,这不是我的母语。

PS: Sorry for my English, it's not my native language.

推荐答案

看起来不错您是否为每封邮件重设/初始化密码对象?你可能不想这样做,但是如果你这样做,你需要仔细考虑密码文件的结构,因为解密器需要知道消息边界在哪里。

Looks pretty good. Are you resetting/initializing the cipher object for every message? You probably don't want to do that, but if you do then you need to think carefully about the structure of the cipher file, because the decryptor needs to know where the message boundaries are.

这篇关于如何正确使用CipherOutputStream加密和解密使用log4j创建的日志(RollingFileAppender)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 18:39