存在Java根CA证书 - 获取SSL握手异常

时间:2017-01-27 18:35:29

标签: java web-services ssl jax-ws

我编写了一个java JAX-WS Web服务客户端。当我尝试使用公共CA签名证书来命中服务器时,我收到了SSL握手异常:

  

com.sun.xml.internal.ws.client.ClientTransportException:HTTP传输错误:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败:sun.security.provider.certpath。 SunCertPathBuilderException:无法找到所请求目标的有效证书路径

我进一步调查并打开了JVM的网络跟踪,发现服务器的公共CA签名证书的颁发者是:

  

发行人:CN = Symantec Class 3安全服务器SHA256 SSL CA,OU = Symantec Trust Network,O = Symantec Corporation,C = US

我已验证此发布者的根CA证书是:

  

CN = VeriSign通用根证书颁发机构,OU =“(c)2008 VeriSign,Inc。 - 仅供授权使用”,OU = VeriSign Trust Network,O =“VeriSign,Inc。”,C = US

我还通过日志跟踪验证了此证书确实已加载。

以下是SSL日志记录跟踪的一部分:

keyStore is : 
keyStore type is : jks
keyStore provider is : 

init keystore
init keymanager of type SunX509
trustStore is: C:\Program Files\Java\jdk1.7.0_79\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is : 
init truststore

[ omitted]

        adding as trusted cert:
      Subject: CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign
, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
      Issuer:  CN=VeriSign Universal Root Certification Authority, OU="(c) 2008 VeriSign
, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
      Algorithm: RSA; Serial number: 0x401ac46421b31321030ebbe4121ac51d
      Valid from Tue Apr 01 17:00:00 PDT 2008 until Tue Dec 01 15:59:59 PST 2037
[ omitted]

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1468680588 bytes = 
Session ID:  {}
Cipher Suites: [ ... ]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names:
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: redacted]
***
[write] MD5 and SHA1 hashes:  len = 181

[omitted]

*** ServerHello, TLSv1
RandomCookie:  GMT: 1524806833 
Session ID:  
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
Extension server_name, server_name: 
***
%% Initialized:  [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]
** TLS_DHE_RSA_WITH_AES_128_CBC_SHA
[read] MD5 and SHA1 hashes:  len = 85

[omitted]

*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=redacted, OU=redacted, O=redacted, L=redacted, ST=redacted, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  modulus:
  public exponent: 65537
  Validity: [From: Sun Oct 16 17:00:00 PDT 2016,
               To: Thu Nov 02 16:59:59 PDT 2017]
  Issuer: CN=Symantec Class 3 Secure Server SHA256 SSL CA, 
          OU=Symantec Trust Network, O=Symantec Corporation, C=US
  SerialNumber: [ ... ]

Certificate Extensions: 9
[1]: ObjectId: 1.3.6.1.4.1.11129.2.4.2 Criticality=false
Extension unknown: DER encoded OCTET string =

[omitted]

***
%% Invalidated:  [Session-1, TLS_DHE_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:

有没有人对可能导致此问题的原因有任何建议?

2 个答案:

答案 0 :(得分:2)

信任树看起来像

root-> VeriSign Universal Root Certification Authority
chain-> Symantec Class 3 Secure Server SHA256 SSL CA
leaf-> somewebsite

您可以拥有多个链或没有链。 浏览器往往在其信任存储中包含根证书以及流行的链证书。

但看起来java信任商店缺少特定的链证书 因此,当您尝试连接到它时,java无法知道叶证书最终是否由根证书信任,因为它没有,它无法找到路径。
有两种方法可以解决这个问题,理想情况下服务器运营商会配置他们的服务器来呈现证书链,如果不可能,你可以手动将链证书导入javas信任库。

Download the cert
导入它

keytool -import -file Example.cer -keystore examplekeystore

答案 1 :(得分:1)

unable to find valid certification path to requested target表示由于

,客户端不信任服务器证书
  1. 从leaf证书到root或
  2. 的链不完整
  3. 根证书在truststore中不存在
  4. 我已检查过Symantec Class 3 Secure Server SHA256 SSL CA VeriSign Universal Root Certification Authority发出的Symantec Class 3 Secure Server SHA256 SSL CA(见Symantec page

    Symantec & Verisign

    Verisign root有效地包含在jdk1.7.0_79中,所以我放弃了2)。因此,我的猜测是服务器端的不完整链。

    操作

    1. 检查https://www.ssllabs.com中的服务器,查找未完成的链错误&#39;。

    2. 验证中间CA是否真的69 87 94 19 d9 e3 62 70 74 9d bb e5 9d c6 68 5e序列号为<maerquee>

    3. 在步骤1中出现错误,下载Symantec证书(从上面的链接)并导入您的信任库

    4. 如果中间证书不是Symantec预期的,那么请获取根CA并将其导入您的信任

    5. 已编辑的SSL信任验证

      证书以层次结构发布。每个证书都由上层颁发者签署,从根CA到叶子证书。数字签名允许检查认证链。

      SSL服务器必须提供证书和链(不包括根)。信任管理器从叶到根检查证书链。如果在信任库中找到任何证书,那么证书就是“受信任的”#34; (即使它已过期......)

      您应该在信任库中包含根CA,而不是叶