了解 Apache HttpClient 中的 SSL (Java)

Understanding SSL in Apache HttpClient (Java)

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

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

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

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

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