首页 > 解决方案 > 了解 Apache HttpClient (Java) 中的 SSL

问题描述

这里有一个自定义 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(),

看来我们需要一些文件和一些密码?

标签: javaapache-httpclient-4.x

解决方案


如果您不指定(使用工厂)上下文,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,此默认信任库通常包含与大多数操作系统和浏览器(如Verisign Symantec)或多或少相同的公共 CA 集Digicert 和 GoDaddy 以及 LetsEncrypt/Identrust。您是否认为默认的 cacerts 是“安全的”是您的选择;如果不是,您可以更改默认文件的内容,或者让您的代码使用不同的文件,并且要执行后者,是的,您必须指定密钥库文件的文件名及其密码。

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

另外:只 为协议指定TLSv1(意思是 1.0)已经过时了,可能被认为是不安全的或至少是临界的。它实际上并没有像 SSLv3(以及很久以前的 SSLv2)那样被彻底打破,因为 BEAST 被证明比人们担心的要温和,但是 TLSv1.1 和 1.2 现在已经被广泛实施和使用,而且 1.3 希望不会太远,所以使用 1.0 被广泛使用被认为是不合标准的,例如适用于许多人的 TLSv1.0 支付卡交易自上周末起被彻底禁止。


推荐阅读