TLS, SSL 및 HTTPS 업그레이드
9436 단어 자바
Diagnosing TLS, SSL, and HTTPS
By: Guest Author
When building inter-connected applications, developers frequently interact with TLS-enabled protocols like HTTPS. With recent emphasis on encrypted communications, I will cover the way in which the JDK evolves regarding protocols, algorithms, and changes, as well as some advanced diagnostics to better understand TLS connections like HTTPS.
Most developers will not have to do this level of diagnosis in the process of writing or running applications. In the event that you do, the following information should provide enough information to understand what's happening within secure connections.
Stability: The evolution of protocols and algorithms
For the last 15 years (since 1998), the Java platform has evolved through the Java Community Process where companies, organizations, and dedicated individuals develop and vote on specifications to determine what makes up the Java Platform. Much of the efforts are centered on compatibility, like the TCK, ensuring that different implementations are compatible with each-other and that developers can predict how their applications will run. We are not changing critical default options (like TLS protocol) within minor versions.
The following chart depicts the protocols and algorithms supported in each JDK version:
JDK 8 (March 2014 to present)
JDK 7 (July 2011 to present)
JDK 6 (2006 to end of public updates 2013)
TLS Protocols
TLSv1.2 (default) TLSv1.1 TLSv1 SSLv3
TLSv1.2 TLSv1.1 TLSv1 (default) SSLv3
TLS v1.1 (JDK 6 update 111 and above) TLSv1 (default) SSLv3
JSSE Ciphers:
Ciphers in JDK 8
Ciphers in JDK 7
Ciphers in JDK 6
Reference:
JDK 8 JSSE
JDK 7 JSSE
JDK 6 JSSE
Java Cryptography Extension, Unlimited Strength (explained later)
JCE for JDK 8
JCE for JDK 7
JCE for JDK 6
Sample Java code for making an HTTPS connection
Making an HTTPS connection in Java is relatively straight-forward. I will post the code here with the intent focused on tuning and understanding the underlying capabilities.
Sample back-end code for making an SSL connection:
final URL url = new URL("https://example.com");
try(final InputStream in = url.openStream()){
//…
}
Or the connection can be tuned through a cast:
final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//operate on conn
conn.connect();
try(final InputStream in = conn.getInputStream()){
//…
}
Example: Qualys SSL Labs' "View My Client"Page
Qualys SSL Labs maintains a collection of tools that are helpful in understanding SSL/TLS connections. One in particular is aView My Client page, which will display information about the client connection. By integrating with that page, I was able to control the implementation as I used different Java tuning parameters.
To test parameter tuning, I implemented a small JavaFX application in JavaScript. It displays that page in aWebView, showing information about the underlying Java SSL/TLS client connection. You can find the code in the appendix.
JSSE Tuning Parameters
When diagnosing TLS-related issues, there are a number of helpful system properties. They are generally covered in their relevant sections of JSSE but this single collection may help anyone looking to understand the flexibility of Java’s implementation or diagnose connection details.
javax.net.debug
Prints debugging details for connections made. Example: -Djavax.net.debug=all or -Djavax.net.debug=ssl:handshake:verbose
https.protocols
Controls the protocol version used by Java clients which obtain https connections through use of the HttpsURLConnection class or via URL.openStream() operations. For older versions, this can update the default in case your Java 7 client wants to use TLS 1.2 as its default. Example: -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 For non-HTTP protocols, this can be controlled through the SocketFactory's SSLContext.
jdk.tls.client.protocols
Controls the underlying platform TLS implementation . Additional information is available in theJSSE Reference Guide. Example: -Djdk.tls.client.protocols=TLSv1.1,TLSv1.2 Available in all JDK 8 releases, or after Java 7 update 95 (January 2016) and Java 6 update 121 (July 2016).
http.agent
When initiating connections, Java will apply this as its user-agent string. Modifying this will handle cases where the receiving party responds differently based on the user-agent. Example: -Dhttp.agent="known agent"
java.net.useSystemProxies
java.net.useSystemProxiesUse proxy details from the operating system itself. Example: -Djava.net.useSystemProxies=true
http.proxyHost http.proxyPort
The proxy connection to use for HTTP connections. Example: -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080
https.proxyHost https.proxyPort
The same as above, except that configuration is separate between HTTP and HTTPS.
http.proxyUser http.proxyPassword https.proxyUser https.proxyPassword
Password-based credentials for the above proxies.
Many other protocols and properties can be found within the following areas:
Example of diagnosing a problem
When making an HTTPS connection, let’s assume that the client threw the following exception due to a failed handshake with the server:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
SSLHandshakeException is a subclass of the IOException, so you do not need to catch is explicitly. Most developers will not need an explicit catch, but it may help you more easily diagnose the cause of any IOException.
When applying the -Djavax.net.debug=all property from above, the failure associated with this SSLHandshakeException would appear immediately after algorithm negotiation in the logs.
JDK 7 (fails on unsupported algorithm)
JDK 8 (works fine)
Cipher Suites: […Long list of ciphers…] Compression Methods: { 0 } Extension elliptic_curves, curve names: {…} Extension ec_point_formats, formats: [uncompressed] Extension server_name, server_name: [host_name: HOST] *** main, WRITE: TLSv1 Handshake, length = 168 main, READ: TLSv1 Alert, length = 2 main, RECV TLSv1 ALERT: fatal, handshake_failure main, called closeSocket() main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Cipher Suites: […Long list of ciphers…] Compression Methods: { 0 } Extension elliptic_curves, curve names: {…} Extension ec_point_formats, formats: [uncompressed] Extension signature_algorithms, signature_algorithms: … Extension server_name, server_name: [type=host_name (0), value=HOST] *** main, WRITE: TLSv1.2 Handshake, length = 226 main, READ: TLSv1.2 Handshake, length = 89 *** ServerHello, TLSv1.2 RandomCookie: GMT: -1809079139 bytes = { …} Session ID: {…} Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 Compression Method: 0 Extension renegotiation_info, renegotiated_connection: Extension ec_point_formats, formats: [uncompressed, ansiX962_compressed_prime, ansiX962_compressed_char2] *** %% Initialized: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256] ** TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 main, READ: TLSv1.2 Handshake, length = 2308
In the case above, the failure occurred during the handshake. The most likely cause for that is algorithm support. The JDK provides a separate package called JCE Unlimited Strength, designed to add stronger algorithm support than what’s available by default. Qualys SSL Labs provides a different server SSL test that will enumerate which algorithms a server supports.
Many TLS error messages are covered in a few pieces of documentation:
Adding stronger algorithms: JCE Unlimited Strength
In a high security environment, one way of strengthening algorithms in the JDK is through the JCE Unlimited Strength policy files. In this particular case, replacing those policy files within JDK 7 allows it to use the stronger variants of existing algorithms and connect successfully.
JCE Unlimited Strength downloads: JDK 8, JDK 7, or JDK 6.
Appendix
The following code will open Qualys SSL Labs’ View My Client page within a Java client. To test configurations, run this like:
jjs -fx viewmyclient.js jjs -fx -Dhttps.protocols=TLSv1 viewmyclient.js
var Scene = javafx.scene.Scene;
var WebView = javafx.scene.web.WebView;
var browser = new WebView();
browser.getEngine().load("https://ssllabs.com/ssltest/viewMyClient.html");
$STAGE.scene = new Scene(browser);
$STAGE.show();
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.