啟用 Java SSL 調試日誌記錄
1. 概述
Java 安全通訊端層 (SSL) 偵錯對於開發人員和管理員診斷和解決與在應用程式中建立安全連線相關的問題至關重要。啟用 SSL 偵錯可以深入了解握手過程、密碼套件協商和其他安全相關活動。
在本教程中,我們將透過一系列實際範例探索啟用 Java SSL 偵錯的各種方法。
2. 為什麼要啟用 SSL 偵錯日誌記錄?
SSL/TLS 協定是確保網際網路資料傳輸安全的基礎。
在應用程式中使用這些協定時,我們可以使用 SSL 偵錯來增強系統中受 SSL 保護的通訊的安全性和效率。它可以幫助我們的一些方式包括:
- 識別證書不符和連接失敗等異常情況
- 監控惡意活動
- 確保我們使用加密演算法的正確實現
- 優化效能
輸出片段可能如下圖所示:
%% 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!"
在此範例中,輸出從會話初始化開始,然後是有關所選密碼套件、金鑰交換參數和握手完成的詳細資訊。它還包括有關安全傳輸的憑證鍊和應用程式資料的資訊。
3. 使用命令列選項
啟用 SSL 偵錯日誌記錄的一種直接方法是透過命令列選項。 Java 允許我們透過javax.net.debug
系統屬性來配置它。此屬性接受各種偵錯選項,允許使用者自訂偵錯輸出的詳細程度:
java -Djavax.net.debug=ssl -jar MyApp.jar
此命令啟動所有 SSL 相關活動的調試。對於更詳細的調試,其他一些有用的選項是:
-
handshake
以獲取 SSL 握手期間的詳細信息 -
keygen
用於獲取密鑰生成詳細信息 -
record
有關記錄層處理的信息
完整的選項清單可以在官方文件中找到。
讓我們利用handshake
選項來產生與握手過程相關的 SSL 日誌:
java -Djavax.net.debug=ssl:handshake -jar MyApp.jar
執行上述命令時,輸出包含握手的詳細資訊。在解決客戶端和伺服器之間建立 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
...
輸出包括有關協商過程的資訊、正在使用的協定版本(在本例中為 TLSv1.2)以及有關客戶端和伺服器之間交換的初始握手訊息的詳細資訊。
4. 使用系統屬性
在某些情況下,我們可能希望在運行時動態啟用 SSL 偵錯日誌記錄。我們可以透過以程式設計方式更改javax.net.debug
系統屬性的值來做到這一點:
static void enableSSLDebugUsingSystemProperties() {
System.setProperty("javax.net.debug", "ssl");
}
讓我們嘗試發起一個虛擬 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);
}
}
}
這種方法允許我們根據應用程式中的特定事件或條件切換登入和關閉:
@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(),"");
}
使用系統屬性啟用 SSL 偵錯可提供快速設置,不需要任何設定檔並允許即時偵錯。
5. 使用日誌設定檔
我們也可以配置Java Logging來擷取SSL偵錯資訊。透過建立logging.properties
檔案並將其放置在類別路徑中,我們可以自訂日誌記錄行為。
讓我們將以下行新增至logging.properties
檔案以啟用日誌記錄:
java.util.logging.ConsoleHandler.level=ALL
java.net.ssl.handlers=java.util.logging.ConsoleHandler
javax.net.ssl.level=ALL
這些屬性告訴控制台處理程序捕獲各個層級的消息。
讓我們透過單元測試來測試新行為:
@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");
}
此方法提供對 SSL 偵錯設定的精細控制,但任何變更通常都需要重新啟動應用程式。
六,結論
在本文中,我們了解了在 Java 中啟用 SSL 偵錯日誌記錄的各種方法,可以利用這些方法來深入了解握手過程、憑證驗證和安全通訊的其他方面。這有助於預防和解決與安全相關的問題。
與往常一樣,完整的源代碼可以在 GitHub 上取得。