简体   繁体   中英

Understanding SSL in Apache HttpClient (Java)

Here there is an example for custom SSL:
https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java

/**
 * This example demonstrates how to create secure connections with a custom SSL
 * context.
 */
public class ClientCustomSSL {

public final static void main(String[] args) throws Exception {
    // Trust own CA and all self-signed certs
    SSLContext sslcontext = SSLContexts.custom()
            .loadTrustMaterial(new File("my.keystore"), "nopassword".toCharArray(),
                    new TrustSelfSignedStrategy())
            .build();
    // Allow TLSv1 protocol only
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
            sslcontext,
            new String[] { "TLSv1" },
            null,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());
    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLSocketFactory(sslsf)
            .build();
    try {

        HttpGet httpget = new HttpGet("https://httpbin.org/");

        System.out.println("Executing request " + httpget.getRequestLine());

        CloseableHttpResponse response = httpclient.execute(httpget);
        try {
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    } finally {
        httpclient.close();
    }
}
}

Why we need that? I've tested an HttpClient request without any SSL thing on it and I'm getting the correct response from HTTPS urls without errors.
What is the problem if I don't add any SSLContext?
And if it's important to make it more secure, what is this line?:

.loadTrustMaterial(new File("my.keystore"), "nopassword".toCharArray(),

it seems we need some file and also some password?

If you don't specify (a factory using) a context, Java (JSSE) uses a default context containing the default truststore, which defaults to the file JRE/lib/security/cacerts (or jssecacerts if present) unless overridden with system properties; see https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores . Depending on whether you are using an Oracle-was-Sun Java package, an IBM or Apple package or Android system, or OpenJDK, this default truststore usually contains more or less the same set of public CAs as most OSes and browsers, like Verisign Symantec Digicert and GoDaddy and LetsEncrypt/Identrust. Whether you consider the default cacerts 'secure' is a choice for you to make; if not you can either change the contents of the default file, or have your code use a different file and to do the latter yes you must specify the filename of the keystore file and its password.

That example uses a custom store because it is an example of custom SSL. If it used the defaults, it would be an example of default SSL not an example of custom SSL. For many actual applications using the defaults is fine.

Aside: specifying only TLSv1 (meaning 1.0) for protocol is way out of date, and is likely to be considered insecure or at least borderline. It hasn't actually been broken outright like SSLv3 (and long ago SSLv2), because BEAST proved tamer than feared, but TLSv1.1 and 1.2 are now widely implemented and used, and 1.3 hopefully not too far away, so using 1.0 is widely considered substandard and for one example applicable to many people TLSv1.0 for payment-card transactions is prohibited outright as of last weekend.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM