Enable Java SSL Debug Logging – 启用 Java SSL 调试日志

最后修改: 2024年 1月 24日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Java Secure Socket Layer (SSL) debugging is crucial for developers and administrators to diagnose and troubleshoot issues related to establishing secure connections in applications. Enabling SSL debugging provides insights into the handshake process, cipher suites negotiation, and other security-related activities. 

Java Secure Socket Layer (SSL) 调试对于开发人员和管理员诊断与在应用程序中建立安全连接相关的问题并排除故障至关重要。启用 SSL 调试可深入了解握手过程、密码套件协商和其他安全相关活动。

In this tutorial, we’ll explore various ways of enabling Java SSL debugging through a series of practical examples.

在本教程中,我们将通过一系列实际示例探索启用 Java SSL 调试的各种方法。

2. Why Enable SSL Debug Logging?

2.为什么要启用 SSL 调试日志?

The SSL/TLS protocols are fundamental for securing data transmission over the internet.

SSL/TLS 协议是确保互联网数据传输安全的基础。

When using these protocols in applications, we can use SSL debugging to enhance both the security and efficiency of SSL-protected communications in our systems. Some of the ways it can help us include:

在应用程序中使用这些协议时,我们可以使用 SSL 调试来增强系统中受 SSL 保护的通信的安全性和效率:

  • Identifying anomalies such as certificate mismatches and connection failures
  • Monitoring against malicious activity
  • Ensuring we’re using the appropriate implementation of an encryption algorithm
  • Optimizing performance

An output snippet might look like this:

输出片段可能是这样的

%% Initialized: [Session-1, SSL_RSA_WITH_AES_256_CBC_SHA]
Cipher Suite: SSL_RSA_WITH_AES_256_CBC_SHA
ServerKeyExchange: EC Diffie-Hellman Server Params: [...]
*** ServerHelloDone
Cert chain length: 1
*** Certificate chain
[...]
Application data: "Hello, World!"

In this example, the output begins with session initialization, followed by details on the chosen cipher suite, key exchange parameters, and the completion of the handshake. It also includes information about the certificate chain and application data being transferred securely.

在本例中,输出以会话初始化开始,随后是所选密码套件、密钥交换参数和握手完成的详细信息。输出还包括证书链信息和安全传输的应用程序数据。

3. Using Command-Line Options

3. 使用命令行选项 4.

One straightforward way to enable SSL debug logging is through the command-line option. Java allows us to configure it via the javax.net.debug system property. This property accepts various debugging options, allowing users to customize the level of detail in the debugging output:

启用 SSL 调试日志的一种直接方法是通过命令行选项。Java 允许我们通过 javax.net.debug 系统属性来配置它。该属性接受各种调试选项,允许用户自定义调试输出的详细程度:

java -Djavax.net.debug=ssl -jar MyApp.jar

This command activates debugging for all SSL-related activities. For more detailed debugging, some other useful options are:

该命令激活所有 SSL 相关活动的调试。要进行更详细的调试,还可以使用其他一些有用的选项:

  • handshake for detailed information during SSL handshake
  • keygen for key generation details
  • record for information about record layer processing

The entire list of options is available in the official documentation.

官方文档中提供了整个选项列表。

Let’s utilize the handshake option to generate SSL logs that pertain to the handshake process:

让我们使用 handshake 选项来生成与握手过程有关的 SSL 日志:

java -Djavax.net.debug=ssl:handshake -jar MyApp.jar

When the above command is executed, the output contains details of the handshake. It’s useful when troubleshooting issues during the initial phase that establishes the SSL/TLS connection between a client and a server. Below is a snippet of the log:

执行上述命令后,输出将包含握手的详细信息。在客户端和服务器之间建立 SSL/TLS 连接的初始阶段排除故障时非常有用。以下是日志片段:

Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
...
main, READ: TLSv1.2 Handshake, length = 232
...
*** ClientHello, TLSv1.2
...

The output includes information about the negotiation process, the protocol version being used (in this case, TLSv1.2), and details about the initial handshake messages exchanged between the client and the server.

输出信息包括协商过程、使用的协议版本(本例中为 TLSv1.2)以及客户端和服务器之间交换的初始握手信息的详细信息。

4. Using System Properties

4. 使用系统属性.

In some scenarios, we may want to enable SSL debug logging dynamically at runtime. We can do this by changing the value of the javax.net.debug system property programmatically:

在某些情况下,我们可能希望在运行时动态启用 SSL 调试日志记录。我们可以通过编程更改 javax.net.debug 系统属性的值来实现这一目的:

static void enableSSLDebugUsingSystemProperties() {
    System.setProperty("javax.net.debug", "ssl");
}

Let’s attempt to initiate a dummy HTTPS request to retrieve the logs:

让我们尝试启动一个虚假 HTTPS 请求来检索日志:

static void makeHttpsRequest() throws Exception {
    String url = "https://github.com/eugenp/tutorials";
    URL httpsUrl = new URL(url);
    HttpsURLConnection connection = (HttpsURLConnection) httpsUrl.openConnection();

    try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
        String line;
        logger.info("Response from " + url + ":");
        while ((line = reader.readLine()) != null) {
            logger.info(line);
        }
    }
}

This approach allows us to toggle logging on and off based on specific events or conditions in our application:

这种方法允许我们根据应用程序中的特定事件或条件切换日志记录的开启和关闭:

@Test
void givenSSLDebuggingEnabled_whenUsingSystemProperties_thenEnableSSLDebugLogging() {
    ByteArrayOutputStream outContent = new ByteArrayOutputStream();
    System.setErr(new PrintStream(outContent));

    SSLDebugLogger.enableSSLDebugUsingSystemProperties();
    assertEquals("ssl", System.getProperty("javax.net.debug"));
    
    SSLDebugLogger.makeHttpsRequest();
    assertTrue(outContent.toString().contains("javax.net.ssl|DEBUG|"));
    outContent.reset();

    System.clearProperty("javax.net.debug");
    assertNull(System.getProperty("javax.net.debug"));
    
    SSLDebugLogger.makeHttpsRequest();
    assertEquals(outContent.toString(),"");
}

Enabling SSL debugging using system properties offers a quick setup that doesn’t require any configuration files and allows for on-the-fly debugging.

使用系统属性启用 SSL 调试可提供快速设置,不需要任何配置文件,并可进行即时调试。

5. Using Logging Configuration File

5.使用日志配置文件

We can also configure Java Logging to capture SSL debugging information. By creating a logging.properties file and placing it in the classpath, we can customize the logging behavior.

我们还可以配置 Java 日志,以捕获 SSL 调试信息。通过创建 logging.properties 文件并将其放置在 classpath 中,我们可以自定义日志记录行为。

Let’s add the following lines to the logging.properties file to enable logging:

让我们在 logging.properties 文件中添加以下几行,以启用日志记录:

java.util.logging.ConsoleHandler.level=ALL
java.net.ssl.handlers=java.util.logging.ConsoleHandler
javax.net.ssl.level=ALL

These properties tell the console handler to capture messages at all levels.

这些属性告诉控制台处理程序捕获所有级别的信息。

Let’s test the new behavior with a unit test:

让我们通过单元测试来测试新行为:

@Test
void givenSSLDebuggingEnabled_whenUsingConfigurationFile_thenEnableSSLDebugLogging() throws IOException {
    InputStream configFile = SSLDebugLoggerUnitTest.class.getClassLoader().getResourceAsStream("logging.properties");
    LogManager.getLogManager().readConfiguration(configFile);

    Logger sslLogger = Logger.getLogger("javax.net.ssl");
    ConsoleHandler consoleHandler = (ConsoleHandler) sslLogger.getHandlers()[0];
    Level consoleHandlerLevel = consoleHandler.getLevel();

    assertEquals(Level.ALL, consoleHandlerLevel, "SSL ConsoleHandler level should be ALL");
}

This approach provides granular control over SSL debugging settings, but any changes typically require an application restart.

这种方法提供了对 SSL 调试设置的细粒度控制,但任何更改通常都需要重启应用程序。

6. Conclusion

6.结论

In this article, we saw various ways of enabling SSL debug logging in Java, which can be leveraged to gain valuable insights into the handshake process, certificate validation, and other aspects of secure communication. This facilitates the prevention and resolution of security-related issues.

在本文中,我们介绍了在 Java 中启用 SSL 调试日志的各种方法,利用这些方法可以深入了解握手过程、证书验证以及安全通信的其他方面。这有助于预防和解决与安全相关的问题。

As always, the full source code is available over on GitHub.

一如既往,您可以在 GitHub 上获取完整的源代码