Java的加密日志记录器

7

我先提出问题:

Java中是否有可用的记录器进行加密(最好是128位AES或更高级别)?

我在过去几天里进行了大量搜索,发现了一些共同的主题:

  • 分析log4j和log4j2之间的信息让我头痛(但与手头的任务无关)
  • 大多数线程都已过时,包括SO上的线程。 这个 可能是我在SO上找到的最好的答案,其中较新的答案链接到自定义版本
  • 最常见的答案是“自定义”,但这些答案也已经过时了。
  • 很多人质疑为什么我或其他人要在Java中执行此操作,因为即使没有源代码,分析Java代码也很简单。
对于最后一点,在我的项目中它几乎没有什么意义。我们还使用代码混淆器,也可以采用其他混淆技术。使用加密的目的只是为了将解决我们的日志问题的门槛提高到“不那么容易”,即使只提高到“稍微费时”。一个稍微相关的侧面 - 我们要加密的记录类型仅用于alpha/beta,很可能只包括调试、警告和错误级别的记录(因此需要加密的消息数量应该相当少)。
我在Log4j2中找到的最好的资料在他们的documentation中:
引用: 密钥提供者 Log4j中的某些组件提供执行数据加密的能力。这些组件需要秘密密钥来执行加密。应用程序可以通过创建实现SecretKeyProvider接口的类来提供密钥。
但我并没有找到除了类似于“插件能够进行加密”之类的含糊陈述外的任何内容。我没有找到一个真正具有这种功能的插件。

我也刚开始尝试寻找其他Java日志记录器,看看它们是否已经实现了加密功能,但是像“java logging encryption”这样的搜索并没有找到什么有用的信息。


1
相关:https://dev59.com/62w15IYBdhLWcg3wcbWy - Jeor Mattan
1个回答

1
基本上,日志加密不是最佳实践,只有在有限的情况下才需要这种功能。因为大多数能够访问日志的人也可以访问JVM,在JVM中所有的日志都至少生成为字符串,所以即使你在日志文件或控制台中对它们进行了加密,真实的值仍然可以在JVM字符串池中找到,如果有人需要黑客你的日志,只需要查看字符串池就像轻而易举。

但是,如果您需要一种加密日志的方法,并且没有通用的方式,则我认为最好的方法是使用Aspect J。这将对您的源代码产生最小的影响,您将像以前一样编写代码,但日志将被加密。以下是一个简单的应用程序代码,它将使用Aspctj、Slf4j作为日志门面和Log4j2作为日志实现来加密所有已编译源的日志。

简单的类记录“Hello World”的日志

public class Main {

    private static final transient Logger LOG = LoggerFactory
        .getLogger(Main.class);

    public static void main(String[] args) {
        LOG.info("Hello World");
        LOG.info("Hello {0}", "World 2");
    }

}

这里涉及到加密(在此情况下只是编辑文本)的方面。

@Aspect
public class LogEncryptAspect {

    @Around("call(* org.slf4j.Logger.info(..))")
    public Object encryptLog (ProceedingJoinPoint thisJoinPoint) throws Throwable{
         Object[] arguments = thisJoinPoint.getArgs();
         if(arguments[0] instanceof String){
             String encryptedLog = encryptLogMessage ((String) arguments[0], arguments.length > 1 ? Arrays.copyOfRange(arguments, 1, arguments.length) : null);
            arguments[0] = encryptedLog;
         }
            
        return thisJoinPoint.proceed(arguments);
    }
    // TODO change this to apply some kind of encryption    
    public final String encryptLogMessage (String message, Object... args){
        if(args != null){
            return MessageFormat.format(message, args) + " encrypted";
        }
        return message + " encrypted";
    }

}

输出结果为:

[main] INFO xxx.Main - Hello World 加密

[main] INFO xxx.Main - Hello World 2 加密


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接