【问题处理】SSLException: Received fatal alert: internal_error

一、简报:

现象描述:javax.net.ssl.SSLException: Received fatal alert: internal_error

问题定位:不同版本jdk对ssl/tsl的支持程度不同。我遇到的问题是jdk1.6不支持tlsv1.2导致;

处理登记:jdk版本升级到1.7之后不再报错。

 

二、详细过程

1、报错信息

客户端访问服务端报错,如下图:

2018-09-13 17:37:21,872 E ReqAcquirer-00445821(default) [HttpClientComm      ] - 专线(7-1-2-2-1) @ 组件执行出错,进入异常处理
javax.net.ssl.SSLException: Received fatal alert: internal_error
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[na:1.8.0_162]
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) ~[na:1.8.0_162]
        at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2038) ~[na:1.8.0_162]
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1135) ~[na:1.8.0_162]
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385) ~[na:1.8.0_162]

2、问题初步分析

httpclient发送请求,应该不是客户端的问题。并且客户端没有对服务端证书做验证,强制信任。所以不应该是客户端报错。

一个可行的方式,网络抓包。服务器通过tcpdump抓网络包,下载文件,通过wireshark打开解析。简单命令如下,需要root权限,详细命令通过tcpdump --help 和man tcpdump可查看。

#tcpdump --help
#tcpdump host somehostip and port someport -w client2server.cap

通过wireshark解析如下:

【问题处理】SSLException: Received fatal alert: internal_error_第1张图片     然而这次分析,我并没有看出太多有用的信息。

3、https网络协议交互

对于https的握手阶段,我搜索了一张简单直白的图片。

【问题处理】SSLException: Received fatal alert: internal_error_第2张图片

 

对于每一步的解释如下:

步骤 1: 客户端通过发送 Client Hello 报文开始 SSL 通信。报文中包含客户端支持的 SSL 的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法密钥长度等)。
步骤 2: 服务器可进行 SSL 通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL 版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
步骤 3: 之后服务器发送 Certificate 报文。报文中包含公开密钥证书
步骤 4: 最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的SSL握手协商部分结束。
步骤 5: SSL 第一次握手结束之后,客户端以 Client Key Exchange 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。
步骤 6: 接着客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。
步骤 7: 客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
步骤 8: 服务器同样发送 Change Cipher Spec 报文。
步骤 9: 服务器同样发送 Finished 报文。
步骤 10: 服务器和客户端的 Finished 报文交换完毕之后,SSL 连接就算建立完成。当然,通信会受到 SSL 的保护。从此处开始进行应用层协议的通信,即发送 HTTP请求。
步骤 11: 应用层协议通信,即发送 HTTP 响应。
步骤 12: 最后由客户端断开连接。断开连接时,发送 close_notify 报文。上图做了一些省略,这步之后再发送 TCP FIN 报文来关闭与 TCP 的通信。在以上流程中,应用层发送数据时会附加一种叫做 MAC(Message Authentication Code)的报文摘要。MAC 能够查知报文是否遭到篡改,从而保护报文的完整性。
下面是对整个流程的图解。图中说明了从仅使用服务器端的公开密钥证书(服务器证书)建立 HTTPS 通信的整个过程

4、net.debug查看信息

了解了如上https的交互内容,那我们可以强行前进了。到底出现在了哪一部分?

在程序启动脚本中我们增加配置项:javax.net.debug=SSl

javax.net.debug=[ssl|all]
If ssl, turns on SSL debugging. If all, turns on SSL debugging with verbose messages.

 

开启了网络SSL的debugging,我们看到可客户端和服务端交互的更多细节:

trustStore is: /home/bsp/jdk1.8.0_162/jre/lib/security/cacerts
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
  Subject: CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US
  Issuer:  CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US
  Algorithm: RSA; Serial number: 0xc3517
  Valid from Mon Jun 21 12:00:00 CST 1999 until Mon Jun 22 12:00:00 CST 2020

adding as trusted cert:
  Subject: CN=Entrust Root Certification Authority - EC1, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US
  Issuer:  CN=Entrust Root Certification Authority - EC1, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US
  Algorithm: EC; Serial number: 0xa68b79290000000050d091f9
  Valid from Tue Dec 18 23:25:36 CST 2012 until Fri Dec 18 23:55:36 CST 2037

adding as trusted cert:
  Subject: CN=SecureTrust CA, O=SecureTrust Corporation, C=US
  Issuer:  CN=SecureTrust CA, O=SecureTrust Corporation, C=US
  Algorithm: RSA; Serial number: 0xcf08e5c0816a5ad427ff0eb271859d0
  Valid from Wed Nov 08 03:31:18 CST 2006 until Tue Jan 01 03:40:55 CST 2030

......(此处省略N多个证书)

adding as trusted cert:
  Subject: CN=KEYNECTIS ROOT CA, OU=ROOT, O=KEYNECTIS, C=FR
  Issuer:  CN=KEYNECTIS ROOT CA, OU=ROOT, O=KEYNECTIS, C=FR
  Algorithm: RSA; Serial number: 0x1121bc276c5547af584eefd4ced629b2a285
  Valid from Tue May 26 08:00:00 CST 2009 until Tue May 26 08:00:00 CST 2020

adding as trusted cert:
  Subject: CN=DigiCert Global Root G2, OU=www.digicert.com, O=DigiCert Inc, C=US
  Issuer:  CN=DigiCert Global Root G2, OU=www.digicert.com, O=DigiCert Inc, C=US
  Algorithm: RSA; Serial number: 0x33af1e6a711a9a0bb2864b11d09fae5
  Valid from Thu Aug 01 20:00:00 CST 2013 until Fri Jan 15 20:00:00 CST 2038

trigger seeding of SecureRandom
done seeding SecureRandom
trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1520046760 bytes = { 246, 213, 192, 77, 83, 196, 208, 176, 204, 116, 200, 95, 35, 121, 105, 94, 138, 108, 50, 253, 44, 8, 137, 203, 125, 27, 51, 164 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension extended_master_secret
***
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, WRITE: TLSv1.2 Handshake, length = 213
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, READ: TLSv1.2 Handshake, length = 652
*** ServerHello, TLSv1.2
RandomCookie:  GMT: 1520046909 bytes = { 232, 185, 231, 33, 209, 40, 98, 148, 20, 177, 225, 135, 113, 195, 49, 232, 170, 131, 87, 27, 165, 211, 11, 147, 102, 194, 199, 190 }
Session ID:  {91, 154, 19, 61, 215, 22, 4, 237, 187, 180, 61, 215, 190, 132, 29, 16, 215, 91, 34, 217, 220, 113, 154, 65, 48, 43, 81, 238, 94, 79, 21, 0}
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: 
***
%% Initialized:  [Session-3, TLS_RSA_WITH_AES_128_CBC_SHA256]
** TLS_RSA_WITH_AES_128_CBC_SHA256
*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=XXXX, OU=XXXX, O=XXXX, L=XXXX, ST=XXX, C=ZN
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 1024 bits
  modulus: 109660329459022741437327619671185182724841857765365169921016424994461637474017405477331233293849582577525594525417222259293946192607547979725687997737705435309372352898249675054641345778050522664011255588691309420287663442328544092938577243341014550159599942338331465012863451437949619972693990304194043657157
  public exponent: 65537
  Validity: [From: Mon May 07 19:17:10 CST 2018,
               To: Thu May 04 19:17:10 CST 2028]
  Issuer: CN=XXXX, OU=XXXX, O=XXXX, L=XXXXXX, ST=XX, C=ZN
  SerialNumber: [    5af035b6]

]
  Algorithm: [SHA1withRSA]
  Signature:
0000: 4F E7 8E 68 26 DB 61 EB   6F C9 AA E0 C5 7E 09 2D  O..h&.a.o......-
0010: A1 E8 5B 60 F0 D1 E0 3F   EF C1 AF 20 8D 45 20 9C  ..[`...?... .E .
0020: E2 6B F5 31 D6 FB 74 38   C3 B7 7C CF E8 27 E7 A7  .k.1..t8.....'..
0030: 0F DE C4 87 23 E2 71 F1   F8 DB DF 74 5D 58 31 5C  ....#.q....t]X1\
0040: 9A C7 52 3F F2 94 4A 11   50 AF 04 8C D4 31 19 F3  ..R?..J.P....1..
0050: 44 24 07 F5 40 81 7F 01   D5 95 53 75 1E A6 58 93  [email protected].
0060: 8A 99 2E 1F F4 A5 6E 1A   9C 2B 01 E0 25 B2 CC C2  ......n..+..%...
0070: 6A 7A FF 33 84 6A CA 8B   DF 78 EB F6 CF 5C 4B 62  jz.3.j...x...\Kb

]
***
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1.2
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, WRITE: TLSv1.2 Handshake, length = 134
SESSION KEYGEN:
PreMaster Secret:
0000: 03 03 DC 25 D9 AD D2 6E   F7 40 F4 29 4F 1C C5 83  ...%...n.@.)O...
0010: 93 98 AA 96 67 17 94 93   37 9D 77 F3 80 BA 32 19  ....g...7.w...2.
0020: CB 64 B9 64 4A 97 E9 CB   82 21 A3 12 40 CB C5 8C  .d.dJ....!..@...
CONNECTION KEYGEN:
Client Nonce:
0000: 5B 9A 13 A8 F6 D5 C0 4D   53 C4 D0 B0 CC 74 C8 5F  [......MS....t._
0010: 23 79 69 5E 8A 6C 32 FD   2C 08 89 CB 7D 1B 33 A4  #yi^.l2.,.....3.
Server Nonce:
0000: 5B 9A 13 3D E8 B9 E7 21   D1 28 62 94 14 B1 E1 87  [..=...!.(b.....
0010: 71 C3 31 E8 AA 83 57 1B   A5 D3 0B 93 66 C2 C7 BE  q.1...W.....f...
Master Secret:
0000: A5 E4 73 1B 10 AA 2B 54   2A AD C1 13 10 8D CF 9D  ..s...+T*.......
0010: 18 44 E2 E5 CF E5 F8 2A   6B 22 2F C2 42 20 3A 8A  .D.....*k"/.B :.
0020: 52 3F 49 8D 60 B2 50 8A   22 EA 74 67 5D 34 D4 F1  R?I.`.P.".tg]4..
Client MAC write Secret:
0000: 1F E6 44 34 EF 15 79 83   AD E1 1C 1C 56 FD D7 3A  ..D4..y.....V..:
0010: 7A E6 F6 0F 09 2B AB 04   E8 BB 30 C1 42 7E 32 AC  z....+....0.B.2.
Server MAC write Secret:
0000: AC D5 BC E5 DE E0 AB CF   C4 44 95 DE 16 0B 5A E9  .........D....Z.
0010: E1 A7 79 D7 CB 31 86 5E   5E CE 0D D9 C3 7E 32 A5  ..y..1.^^.....2.
Client write key:
0000: 83 01 24 CE 30 38 DF E9   22 34 3F F1 5B 8A 16 9A  ..$.08.."4?.[...
Server write key:
0000: EB 7E 65 67 93 70 36 57   84 73 5F 7E 1B 0F 68 1F  ..eg.p6W.s_...h.
... no IV derived for this protocol
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 129, 146, 65, 253, 207, 111, 59, 106, 159, 92, 106, 141 }
***
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, WRITE: TLSv1.2 Handshake, length = 80
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, READ: TLSv1.2 Alert, length = 2
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, RECV TLSv1.2 ALERT:  fatal, internal_error
%% Invalidated:  [Session-3, TLS_RSA_WITH_AES_128_CBC_SHA256]
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, called closeSocket()
NBPS.NBPSOUTTER.ReqAcquirerAliPay/ReqAcquirer-2, handling exception: javax.net.ssl.SSLException: Received fatal alert: internal_error

 大家可以自行对照SSL的日志及HTTPS的交互过程对照,发线在上图的倒数第四行的报错信息:

RECV TLSv1.2 ALERT:  fatal, internal_error

尽管我还是不知道发生了什么。但是,知道了一件事:当客户端发送*** Finished verify_data即全部报文的整体校验值后,服务器没搭理客户端。那我们理直气壮地去找服务端问问。额,其实问不出什么来。

5、问题原因

但是了解到服务端的JDK版本为1.6。直接贴oracle官网图:

【问题处理】SSLException: Received fatal alert: internal_error_第3张图片

服务端采用的1.6jdk根本不支持TLSv1.2。那来一次验证,当把版本升到jdk1.7之后,再发交易,顺利通过。

此时客户端还需要做一件事情,通过设置首选协议及最高支持协议,不展开讲。

-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
-Djdk.tls.client.protocols=TLSv1	

 

 

 

 

参考链接:

1、Oracle® Application Server Containers for J2EE User's Guide

https://docs.oracle.com/cd/B25016_06/doc/dl/web/B14011_02/apdx_a.htm#r28c1-t8

2、Diagnosing TLS, SSL, and HTTPS

https://blogs.oracle.com/java-platform-group/diagnosing-tls,-ssl,-and-https

3、《图说HTTP》上野 宣 (作者) 于均良 (译者)

4、《Https协议详解》https://www.cnblogs.com/zxj015/p/6530766.html

 

你可能感兴趣的:(java,oracle,https)