安全/加密log4j文件

我有个问题 ; 安全要求我有java swing应用程序,它具有log4j生成的日志文件,用于跟踪错误时的支持问题。

我必须ecrypt / cypher / secure文件,以便客户端无法打开它们并查看它们(至少不是人类可读的方式),同时当支持技术团队获取这些文件时,他们将知道如何阅读( 解密 )它们。

我做了很多搜索,我尝试了我发现的最佳选项,即通过扩展SkeletonAppender构建自定义appender。

现在知道我有log4j工作得很好,如下面的配置,但我创建了新的类来加密它但我不能让它工作,即使简单的设置它不会创建文件,所以我可以继续在ecnryption部分。

任何帮助,链接都很好。

工作…版本

            

不工作……版本

                 

简单的class级考试

http://www.javaworld.com/article/2075817/core-java/customized-appender-extending-org-apache-log4j-fileappender.html

 package com.MyAppender; import org.apache.log4j.spi.LoggingEvent; public class MyAppender extends org.apache.log4j.RollingFileAppender { private String file; private boolean initialized = false; private String baseFileName = null; // private static final Log log = LogFactory.getLog(MyAppender.class); /** * * write to ActivityLog * * @param event * logging event invoked. * */ @Override protected void subAppend(LoggingEvent event) { if (!initialized) { createNewFile(); } synchronized (this) { super.subAppend(event); } } /** * * create a new ActivityLog File * */ public void createNewFile() { try { baseFileName = file; super.setFile(baseFileName); super.activateOptions(); initialized = true; } catch (Exception e) { // log.error("*#*Error in configuration of log4j params,unable to create ActivityLog file"); } } /** * * invokes File Appender's activateOptions() which controls the creation of * log files. * */ @Override public void activateOptions() { super.setFile(file); super.activateOptions(); } /** * * Close and rename the current ActivityLog file and reset counter and * timestamp. * */ public void rollOver() { closeFile(); initialized = false; } @Override public void setFile(String file) { this.file = file; } } 

然后我计划在Cipher OutputStream中实现代码

该问题的一个可能的解决方法是将日志写入支持加密的嵌入式数据库,例如H2本身支持加密, SQLite具有开源加密扩展 – 这样您就可以使用JDBCAppender并让数据库负责加密而无需加密担心自定义appender。


从这个问题 ,SQLite配置看起来像

        

您的日志表的样子

 CREATE TABLE Log ( LogId INTEGER PRIMARY KEY, Date DATETIME NOT NULL, Level VARCHAR(50) NOT NULL, Logger VARCHAR(255) NOT NULL, Message TEXT DEFAULT NULL ); 

可以在此处找到有关JDBCAppender文档


SQLite的官方加密扩展以及至少一个第三方开源扩展; 我从来没有必要加密SQLite,但如果我必须这样做,那么我会使用官方扩展,除非我遇到问题。


如果您在客户端上运行此操作,那么理想情况下,您将能够在启动时将程序电话置于家中以获取数据库加密密钥,以便密钥永远不会存在于客户端的磁盘驱动器上(忽略它的可能性)到交换文件) – 客户端仍然可以使用调试器或其他任何东西来尝试获取密钥内存,但可能他们对解密日志没有足够的兴趣来解决这个问题。 如果你必须在客户端存储密钥,那么你可以在使用它之前至少对它进行几次哈希处理,例如在程序中对base_key进行硬编码,然后在启动时通过运行base_key来创建actual_key。通过SHA512 (或其他)几次; 客户端仍然可以通过使用调试器来确定您正在做什么,但他们希望他们再也不希望遇到麻烦。

选项1:使用自定义SocketAppender

作为Zim-Zam关于使用支持JDBC的appender的回答的替代方法(顺便说一下,如果沿着这条路线走,也记得启用安全传输),你也可以考虑使用SocketAppender并推出自己的加密方法。

选项2:使用Flume和FlumeAppender

请参阅有关appender的log4j文档,并查看使用支持事件加密的FlumeAppender

使用主代理和辅助代理配置的FlumeAppender配置示例,压缩主体,使用RFC5424Layout格式化主体,并将加密事件持久保存到磁盘。 此示例“压缩正文,使用RFC5424Layout格式化正文,并将加密事件持久保存到磁盘:”

       MySecretProvider         

有趣的读物

这不直接回答您的问题,但也非常有趣: 创建加密的日志文件

我觉得你看起来像这样。 虽然我不建议使用它。 如果您使用代码发送密钥,那么有很多反编译器可以反编译jar / class文件并获得“密钥”。 否则你应该使用PKI和所有..? 我这里没有考虑那个选项。

扩展RollingFileAppender类

 public class EncryptedRollingFileAppender extends RollingFileAppender 

因为RollingFileAppender类不是最终类所以你可以做到。

覆盖方法

 public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize) throws IOException 

这样的事情。

  LogLog.debug("setFile called: " + fileName + ", " + append); // It does not make sense to have immediate flush and bufferedIO. if (bufferedIO) { setImmediateFlush(false); } reset(); OutputStream ostream = null; try { // // attempt to create file // // ostream = new FileOutputStream(fileName, append); ostream = this.createEncryptedOutputStream(fileName, append); } catch (FileNotFoundException ex) { // // if parent directory does not exist then // attempt to create it and try to create file // see bug 9150 // String parentName = new File(fileName).getParent(); if (parentName != null) { File parentDir = new File(parentName); if (!parentDir.exists() && parentDir.mkdirs()) { // ostream = new FileOutputStream(fileName, append); try { ostream = this.createEncryptedOutputStream(fileName, append); } catch (Exception e) { e.printStackTrace(); } } else { throw ex; } } else { throw ex; } } catch (Exception e) { throw new FileNotFoundException(); } Writer fw = createWriter(ostream); if (bufferedIO) { fw = new BufferedWriter(fw, bufferSize); } this.setQWForFiles(fw); this.fileName = fileName; this.fileAppend = append; this.bufferedIO = bufferedIO; this.bufferSize = bufferSize; writeHeader(); LogLog.debug("setFile ended"); if (append) { File f = new File(fileName); ((CountingQuietWriter) qw).setCount(f.length()); } 

大多数代码都是从基类复制的。

加密私有方法应该看起来像这样

  private OutputStream createEncryptedOutputStream(String filename, boolean append) throws FileNotFoundException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException { CipherOutputStream cstream = 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); cstream = new CipherOutputStream(new FileOutputStream(filename, append), cipher); } catch (FileNotFoundException e) { throw e; } return (cstream); } 

您不会失去RollingFileAppender的任何function。 您也可以对其他appender进行类似的编码。

免责声明: – 如果您正在使用它,请不要使用这些密钥@ production。 再次,你用jar子装运钥匙。 一个聪明的黑客可以轻松地破解事物。因为它是“记录”,所以要完成的代码调整。 我还没有测试过这段代码。