(1)老规矩,先加参数:-Djavax.net.debug=all 得到握手过程: client hello server hello 然后就报错了:
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT: fatal, description = certificate_unknown main, WRITE: TLSv1 Alert, length = 2 [Raw write]: length = 7 0000: 15 03 01 00 02 02 2E ....... main, called closeSocket() main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
但是jdk8就是成功的。 然后发现jdk8用的tlsv1.2,jdk7是tlsv1
(2)添加jvm参数-Djdk.tls.client.protocols=TLSv1.2 -Dhttps.protocols=TLSv1.2 或者 System.setProperty("https.protocols","TLSv1.2"); System.setProperty("https.cipherSuites","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
抓包看,确实是用的1.2,但是依然报错,真是见鬼了。
(3)焦点放到TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA上,想着jdk7带的加密算法不够吗? https://www.oracle.com/java/technologies/javase-jce7-downloads.html 搜了半天,在这里下载了扩展包,解压,扔到\jre\lib\security下覆盖 然后涛声依旧。
(4)蒙圈了一晚上
(5)早上5点,想起来,把网站证书手动导入一下,发现竟然好使了。 然后与jdk8对比了一下,发现匹配的证书不一样。
jdk8是这样:
Found trusted certificate ( "certificate" : { "version" : "v3", "serial number" : "03 3A F1 E6 A7 11 A9 A0 BB 28 64 B1 1D 09 FA E5", "signature algorithm": "SHA256withRSA", "issuer" : "CN=DigiCert Global Root G2, OU=www.digicert.com, O=DigiCert Inc, C=US", "not before" : "2013-08-01 20:00:00.000 CST", "not after" : "2038-01-15 20:00:00.000 CST", "subject" : "CN=DigiCert Global Root G2, OU=www.digicert.com, O=DigiCert Inc, C=US",
jdk7是这样:
Found trusted certificate: [ [ Version: V3 Subject: CN=cloud.xxx.com Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits modulus: 22067186895045798635271210367697924555471573457867716592202049557200054225010703344633970743651927576104316744289065287242744087573534456962122963206520944900317681399716002685107084602763696051215537234741642461987984572572815827817790076424676504393211736452953035664727336111786201803481572019581043259314629195073462229887316274406556967978479089801493052163980319457804693802515455979279399200329409787383294524950133140135181217959438353950950870112536783358033005876552162218427948868206869435701718337363898558799978987827267068632077281857522140867855510923986304228498927657786169226965409568720342066150069 public exponent: 65537 Validity: [From: Mon Mar 20 08:00:00 CST 2023, To: Thu Mar 21 07:59:59 CST 2024] Issuer: CN=Encryption Everywhere DV TLS CA - G2, OU=www.digicert.com, O=DigiCert Inc, C=US SerialNumber: [ 04c40fd8 9ae852f6 5e30de03 28de083d]
证书是三层结构,jdk8匹配的是root顶级证书,jdk7匹配的是网站的证书,也就是我手动导入的。 那么,想到,是不是jdk7缺root证书呢。
打开cacerts文件一看,果然。 jdk7没有DigiCert Global Root G2证书,只有DigiCert Global Root CA证书。 从jdk8导出证书,然后导入到jdk7里,OK了。 哈哈哈。
(6)归根结底,是jdk版本太低了。 https://bugs.openjdk.org/browse/JDK-8145954 https://bugs.java.com/bugdatabase/view_bug?bug_id=8145954 高版本,人家添加这些root证书了。
(7)2023年3月8日,DigiCert将开始将所有TLS/SSL证书品牌的默认公开颁发更新为第二代(G2)根层次结构。所以,最近才发现。
|