如何正确使用CipherOutputStream加密和解密用log4j创建的日志(RollingFileAppender)
我在加密/解密log4j的RollingFileAppender生成的日志文件时遇到问题。 对于加密我试图扩展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:对不起我的英语,这不是我的母语。
看起来不错。 您是否为每条消息重置/初始化密码对象? 您可能不希望这样做,但如果您这样做,则需要仔细考虑密码文件的结构,因为解密器需要知道消息边界的位置。
- Java JDBC效率:连接需要多长时间?
- org.h2.Driver的java ClassNotFoundException
- 在JBoss AS 6中监听登录事件
- listFiles()的文件无法处理符号链接?
- 引发了一个SQLException,java.lang.InterruptedException,我是否用完了数据库连接?
- 如何在Selenium Webdriver中获取元素的文本()
- 何时加密需要填充?
- java-cassnadra object地址映射的冻结注释<text,frozen <list <frozen >>>,
- IntStream何时实际关闭? SonarQube S2095对IntStream是误报吗?