了解Apache HttpClient(Java)中的SSL

时间:2018-07-03 22:18:21

标签: java apache-httpclient-4.x

以下是自定义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();
    }
}
}

为什么我们需要那个?我已经测试了没有任何SSL内容的HttpClient请求,并且从HTTPS URL得到了正确的响应,没有错误。
如果我不添加任何SSLContext会有什么问题?
如果重要的是使其更加安全,这行是什么?:

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

似乎我们需要一些文件和一些密码?

1 个答案:

答案 0 :(得分:3)

如果不指定(使用工厂)上下文,则Java(JSSE)使用包含默认信任库的默认上下文,该默认信任库默认为文件JRE/lib/security/cacerts(如果存在,则为jssecacerts)除非被系统属性覆盖;参见https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores。根据您使用的是Oracle-was-Sun Java软件包,IBM还是Apple软件包,Android系统还是OpenJDK,此默认信任库通常包含与大多数OS和浏览器大致相同的公共CA集,例如 Verisign Symantec Digicert和GoDaddy,以及LetsEncrypt / Identrust。是否选择默认的cacerts“安全”是您要做出的选择。如果不是,则可以更改默认文件的内容,或者让代码使用其他文件,如果要使用其他文件,则必须指定密钥库文件的文件名及其密码。

该示例使用自定义存储,因为它是自定义SSL的示例。如果使用默认值,则它将是默认SSL的示例,而不是自定义SSL的示例。对于许多实际的应用程序,使用默认值就可以了。

此外:仅为协议指定 TLSv1(意味着1.0)已过时,并且 可能被认为是不安全的或至少是边界。实际上,它并没有像SSLv3(和很久以前的SSLv2)那样被彻底打破,因为BEAST被证明比人们想象的要温和得多,但是TLSv1.1和1.2现在得到了广泛的实现和使用,而1.3希望距离不太远,因此广泛使用1.0从上周末开始,禁止将TLSv1.0视为适用于许多人的不合标准的示例,并且该协议非常适用于许多人。