[关闭]
@xtccc 2017-05-17T08:39:45.000000Z 字数 1710 阅读 2325

一些奇怪的异常

给我写信
GitHub

此处输入图片的描述


Java



1. SSL异常:sun.security.validator.ValidatorException: PKIX path building failed


1.1 非正常解决思路

在通过scalaj访问NREL的API时,某天突然报错:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
        at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
        at sun.security.validator.Validator.validate(Unknown Source)

经查,是因为运行这段代码的jdk的jre/lib/security/cacerts跟别的正常机器的文件有些不一样,替换过来就好了。


本地测试:
下载文件 SSLPoke.class
然后执行:

  1. $ java SSLPoke developer.nrel.gov 443

如果返回如下就说明正常了:

  1. $ java SSLPoke developer.nrel.gov 443
  2. Successfully connected

参考: Unable to Connect to SSL Services due to PKIX Path Building Failed


1.2 允许访问非安全网站

如果我们允许Java程序访问非安全的网站,则即使没有证书,也不会报异常:

  1. val resp: HttpResponse[String] = WithException {
  2. Http(url)
  3. .option(HttpOptions.connTimeout(60000))
  4. .option(HttpOptions.readTimeout(60000))
  5. // must set this, otherwise will see exception:
  6. // sun.security.validator.ValidatorException:
  7. // PKIX path building failed:
  8. // sun.security.provider.certpath.SunCertPathBuilderException:
  9. // unable to find valid certification path to requested target
  10. .option(HttpOptions.allowUnsafeSSL)
  11. .asString
  12. }.asInstanceOf[HttpResponse[String]]
  13. val body: String = resp.body


1.3 访问时提供证书

实际上本质原因是我们的Java app通过HTTPS链接无法识别被访问网站的root certificate authentication (CA)

如果要求Java程序必须以安全的形式来访问网站,则必须将目标网站的证书提供给Java程序。

参考 这里

1.2.1 查看远端server的证书

用Chrome打开目标网站:https://developer.nrel.gov/

打开 View -> Developer -> Developer Tools,然后点击Security可以看到:
image_1bg7e222p6gc1aj41n4fl609pe9.png-103.1kB

然后点击 View certificate,就能看到三级证书:
image_1bg7e4vjnqqod5lgaesg39tfm.png-104.9kB

下面把证书导出来(首先安装工具gnutls-bin):

  1. $ gnutls-cli --print-cert developer.nrel.gov < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > developer.nrel.gov.cert

好了,可以看到本地生成了一个证书文件developer.nrel.gov.cert。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注