java - 了解 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(),
看来我们需要一些文件和一些密码?
解决方案
如果您不指定(使用工厂)上下文,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 支付卡交易自上周末起被彻底禁止。
推荐阅读
- java - 优化:具有最大值的受限整数分区
- javascript - React - ref 的当前函数在 if 语句上失败
- python - 阅读所有工作表擅长 python
- python - 操作系统无法加载图像 pygame.error: 无法打开 imgs\pipe.png
- c++ - C++ 分段错误——自平衡树插入
- scheme - repl.it 方案中缺少函数?
- javascript - Vue js中嵌套数组的总数
- python - Clean way to combine list of lists into a dictionary?
- google-maps-markers - 在谷歌地图 api 上显示 50,000 个标记的最佳方法是什么
- image-processing - 如何解码 exif UserComment?