【发布时间】:2016-09-16 23:54:17
【问题描述】:
我在 Wildfly 9 中配置有效证书(不是自签名!)时遇到问题。我已在 Wildfly 中配置了 HTTPS 连接器:
<https-listener name="https" socket-binding="https" security-realm="UndertowRealm" />
安全领域:
<security-realm name="UndertowRealm">
<server-identities>
<ssl>
<keystore path="domain.p12" relative-to="jboss.server.config.dir" keystore-password="password"
alias="appcert" />
</ssl>
</server-identities>
</security-realm>
并使用以下命令生成密钥库:
openssl pkcs12 -export -in domain.crt -inkey domain.key -out domain.p12 -name appcert -CAfile cafile.crt -caname root现在,当我在浏览器中打开应用程序时,一切正常。浏览器将证书识别为有效证书,而不会像在自签名证书中那样提示异常。
但是,当我尝试通过 SSLPoke.java 连接到同一个 URL 时,出现以下异常:
javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径 在 sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 在 sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) 在 sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) 在 sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) 在 sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) 在 sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) 在 sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) 在 sun.security.ssl.Handshaker.process_record(Handshaker.java:914) 在 sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) 在 sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) 在 sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747) 在 sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) 在 sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138) 在 SSLPoke.main(SSLPoke.java:26) 原因:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径 在 sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) 在 sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) 在 sun.security.validator.Validator.validate(Validator.java:260) 在 sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) 在 sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) 在 sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) 在 sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ... 9 更多 原因:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径 在 sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) 在 sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) 在 java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) 在 sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ... 15 更多如果我在客户端中导入证书,这个错误就会消失,但我认为我不应该这样做,因为这是一个有效的证书。
测试代码如下:
导入 java.io.InputStream; 导入 java.io.OutputStream; 导入 javax.net.ssl.SSLSocket; 导入 javax.net.ssl.SSLSocketFactory; /** 建立到主机和端口的 SSL 连接,写入一个字节和 * 打印响应。看 * http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services */ 公共类 SSLPoke { 公共静态无效主要(字符串[]参数){ if (args.length != 2) { System.out.println("用法:"+SSLPoke.class.getName()+" "); System.exit(1); } 尝试 { SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1])); InputStream in = sslsocket.getInputStream(); 输出流输出 = sslsocket.getOutputStream(); // 写一个测试字节来得到一个反应 :) out.write(1); 而(in.available()> 0){ System.out.print(in.read()); } System.out.println("连接成功"); } 捕捉(异常异常){ 异常.printStackTrace(); } } }为什么会发生这种情况,设置 SSL 证书的正确方法是什么?
【问题讨论】: