REST client call fails with "SunCertPathBuilderException: unable to find valid certification path to requested target"

huangapple go评论76阅读模式
英文:

REST client call fails with "SunCertPathBuilderException: unable to find valid certification path to requested target"

问题

我正在尝试在本地测试两个应用程序。一个是REST API服务器,另一个是REST客户端。服务器在eclipse中以Open Liberty运行。客户端作为eclipse中的JUnit测试运行。

我已将公司证书安装在eclipse JRE和服务器配置的信任存储中。单元测试被配置为使用已安装证书的JRE,并且我还在运行配置中明确设置了信任存储位置:

-Djavax.net.ssl.keyStore="C:\Program Files\Java\jre\lib\security\cacerts"
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.ssl.trustStore="C:\Program Files\Java\jre\lib\security\cacerts"
-Djavax.net.ssl.trustStorePassword=changeit
-Djavax.net.debug=all

错误消息包含:

Caused by: 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(PKIXValidator.java:450)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:317)
	... 51 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	... 57 more

我启用了SSL调试并看到:

*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=localhost, OU=OpenLibertyServer, O=ibm, C=us
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  params: null
  modulus: <removed.....>
  public exponent: 65537
  Validity: [From: Thu Mar 19 15:08:27 CET 2020,
               To: Fri Mar 19 15:08:27 CET 2021]
  Issuer: CN=localhost, OU=OpenLibertyServer, O=ibm, C=us
  SerialNumber: [    21...29]

Certificate Extensions: 2
[1]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: localhost
]

[2]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: ...                                       
]

调试还列出了存储在信任存储中的所有证书,包括我安装的证书。

这里可能有什么问题或遗漏?

更新

我将客户端的信任存储设置为与服务器使用的完全相同的信任存储,问题就“解决”了。这显然不是实际的解决方案,很可能是证书实际上缺失的指示。至少我可以继续进行测试...

英文:

I am trying to test 2 applications locally. One is a REST API server, the other is a REST client. The server runs on Open Liberty in eclipse. The client runs as a JUnit test in eclipse.

I have installed our company certificate in the truststores of the eclipse JRE and the server configuration. The unit test is configured to use the JRE which has the certificate installed and I also set the truststore location explicitly in the run configuration:

-Djavax.net.ssl.keyStore="C:\Program Files\Java\jre\lib\security\cacerts"
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.ssl.trustStore="C:\Program Files\Java\jre\lib\security\cacerts"
-Djavax.net.ssl.trustStorePassword=changeit
-Djavax.net.debug=all

The error message contains:

Caused by: 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(PKIXValidator.java:450)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:317)
	... 51 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	... 57 more

I enabled SSL debugging and saw

*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=localhost, OU=OpenLibertyServer, O=ibm, C=us
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  params: null
  modulus: <removed.....>
  public exponent: 65537
  Validity: [From: Thu Mar 19 15:08:27 CET 2020,
               To: Fri Mar 19 15:08:27 CET 2021]
  Issuer: CN=localhost, OU=OpenLibertyServer, O=ibm, C=us
  SerialNumber: [    21...29]

Certificate Extensions: 2
[1]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: localhost
]

[2]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: ...                                       
]

The debugging also lists all of the certificates which are in the truststore, including the one I installed.

What might be wrong or missing here?

UPDATE

I set the truststore for the client to be the exact same truststore that the server uses and the problem is 'solved'. This is naturally not realistic solution and is probably an indication that a certificate is actually missing. At least I can continue with testing...

答案1

得分: 1

我不确定你问题的原因是什么,但根据我的经验,在Windows存储中导入受信任的根证书会更容易(可能已由你的公司推送到那里),并且添加这个JVM选项:

-Djavax.net.ssl.trustStoreType=WINDOWS-ROOT
英文:

I'm not sure what's the cause of your problem but in my experience it's easier to import the trusted root certificate in the Windows store (it might already be pushed there by your company) and to add this JVM option:

-Djavax.net.ssl.trustStoreType=WINDOWS-ROOT

答案2

得分: 0

"C:\Program Files\Java\jre\lib\security\cacerts" 是默认的 Java 信任库,您需要在 Java 客户端 cacerts 中添加证书链。
使用工具或 Windows 以 CER 格式导出证书链,然后将其添加到默认的 Java 信任库中,操作如下:

<pre><code>keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias yourCertAlias -file path\to\yourCertificatChain.cer
</code></pre>

或者,如果您想要轻松切换 JRE,可以将证书链放入外部信任库,并使用以下方式调用它:
<pre><code>-Djavax.net.ssl.trustStore=&lt;truststore 路径&gt; -javax.net.ssl.trustStorePassword=&lt;truststore 密码&gt;
</code></pre>
英文:

"C:\Program Files\Java\jre\lib\security\cacerts" is the default java truststore, you need to add certificat chain in the java client cacerts.
Export the certificat chain in CER format with a tool or with Windows and add it in your default java truststore like this:

<pre><code>keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias yourCertAlias -file path\to\yourCertificatChain.cer
</code></pre>

Alternatively if you want to switch of JRE easily you can put certificat chain in an external truststore and call it with :
<pre><code>-Djavax.net.ssl.trustStore=&lt;truststore path&gt; -javax.net.ssl.trustStorePassword=&lt;truststorepassword&gt;
</code></pre>

huangapple
  • 本文由 发表于 2020年10月20日 14:55:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/64439951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定