javahttps.protocols在Java中的使用
代长亚Contents
Caused by: java.io.EOFException: SSL peer shut down incorrectly
在服务器上,发现一个微博爬虫系统偶尔会报这种异常。Google 了下,在 Stackoverflow 上看到相关的回答。所以决定详细了解下这原理。
上面说,明确指定HTTPS的协议版本即可。即:System.setProperty("https.protocols", "TLSv1.1")
HTTPS 的 protocols
查看维基百科,关于 HTTPS 的介绍可知:
严格地讲,HTTPS并不是一个单独的协议,而是对工作在一加密连接(TLS或SSL)上的常规HTTP协议的称呼。
TLS 与 SSL
SSL 是 TLS 的前身。SSL 是 Netscape 公司推出的 HTTPS 协议,以 SSL 进行加密。
IETF 将 SSL 进行标准化,公布了第一版的 TLS 标准文件。
发展历史
SSL
- 1.0 没有公开过
- 2.0 1995年2月发布
- 3.0 1996年发布。2014年10月,Google 发现 SSL 3.0 设计缺陷,建议禁用此一协议。
TLS
IETF 将SSL标准化,并称为 TLS. TLS1.0 与 SSL 3.0 的差异非常小。
- 1.0
- 1.1 2006
- 1.2 2008
- 1.3 2016
JDK中对 HTTPS 版本的支持情况
JDK 6
- SSL v3
- TLS v1(默认)
- TLS v1.1(JDK6 update 111 及以上)
JDK 7
- SSLv3
- TLS v1(默认)
- TLS v1.1
- TLS v1.2
JDK 8
- SSL v3
- TLS v1
- TLS v1.1
- TLS v1.2(默认)
JSSE
JSSE(Java Security Socket Extension),它实现了SSL和TSL(传输层安全)协议。
JSSE 参数调节
javax.net.debug
:打印连接的详细信息。例如 -Djavax.net.debug=all
或者 -Djavax.net.debug=ssl🤝verbose
https.protocols
:控制使用 Java 客户端通过 HttpsURLConnection
或 URL.openStream()
操作的协议版本。例如 -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
. 对于非HTTP协议,可以通过 SocketFactory's SSLContext
来控制 。
jdk.tls.client.protocols
:控制底层平台的TLS实现。例如 -Djdk.tls.client.protocols=TLSv1.1,TLSv1.2
http.agent
:当初始化连接时,Java会使用这个作为 user-agent
的字符串。例如: -Dhttp.agent="known agent"
java.net.useSystemProxies
:使用系统本身的代理: -Djava.net.useSystemProxies=true
http.proxyHost
和 http.proxyPort
: 使用HTTP协议时的代理。例如: -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080
https.proxyHost
和 https.proxyPort
: 和上面一样,区别只是 HTTP 和 HTTPS
http.proxyUser
,http.proxyPassword
, https.proxyUser
,https.proxyPassword
: 认证用户名和密码。
查看服务器支持的 HTTPS 协议版本
1
| nmap --script ssl-enum-ciphers -p 443 api.weibo.com
|
返回的结果为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
| Starting Nmap 7.40 ( https://nmap.org ) at 2017-03-02 14:18 CST Nmap scan report for api.weibo.com (180.149.135.176) Host is up (0.039s latency). Other addresses for api.weibo.com (not scanned): 180.149.135.230 PORT STATE SERVICE 443/tcp open https | ssl-enum-ciphers: | SSLv3: | ciphers: | TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C | TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C | TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C | TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D | compressors: | NULL | cipher preference: server | warnings: | 64-bit block cipher 3DES vulnerable to SWEET32 attack | 64-bit block cipher DES vulnerable to SWEET32 attack | 64-bit block cipher IDEA vulnerable to SWEET32 attack | Broken cipher RC4 is deprecated by RFC 7465 | CBC-mode cipher in SSLv3 (CVE-2014-3566) | Key exchange (dh 1024) of lower strength than certificate key | TLSv1.0: | ciphers: | TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C | TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C | TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C | TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D | compressors: | NULL | cipher preference: server | warnings: | 64-bit block cipher 3DES vulnerable to SWEET32 attack | 64-bit block cipher DES vulnerable to SWEET32 attack | 64-bit block cipher IDEA vulnerable to SWEET32 attack | Broken cipher RC4 is deprecated by RFC 7465 | Key exchange (dh 1024) of lower strength than certificate key | TLSv1.1: | ciphers: | TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C | TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C | TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C | TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D | compressors: | NULL | cipher preference: server | warnings: | 64-bit block cipher 3DES vulnerable to SWEET32 attack | 64-bit block cipher DES vulnerable to SWEET32 attack | 64-bit block cipher IDEA vulnerable to SWEET32 attack | Broken cipher RC4 is deprecated by RFC 7465 | Key exchange (dh 1024) of lower strength than certificate key | TLSv1.2: | ciphers: | TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A | TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A | TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A | TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A | TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_SEED_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_IDEA_CBC_SHA (rsa 2048) - A | TLS_RSA_WITH_RC4_128_SHA (rsa 2048) - C | TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C | TLS_RSA_WITH_DES_CBC_SHA (rsa 2048) - C | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 1024) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A | TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 1024) - A | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C | TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D | compressors: | NULL | cipher preference: server | warnings: | 64-bit block cipher 3DES vulnerable to SWEET32 attack | 64-bit block cipher DES vulnerable to SWEET32 attack | 64-bit block cipher IDEA vulnerable to SWEET32 attack | Broken cipher RC4 is deprecated by RFC 7465 | Key exchange (dh 1024) of lower strength than certificate key |_ least strength: D Nmap done: 1 IP address (1 host up) scanned in 10.99 seconds
|
可知,它支持的协议有:
- SSLv3
- TLSv1.0
- TLSv1.1
- TLSv1.2
解决办法
服务器为Linux + JDK7 + 64位。添加
1
| System.setProperty("https.protocols", "TLSv1.2");
|
在爬虫爬取数据时,就没有报这类似的异常了。
参考资料