信任Java Playframework 2.2中的所有SSL证书

我试图在Play框架中调用Web服务(具有自签名SSL证书)使用以下函数:

public static play.libs.F.Promise webcall() { String feedUrl = "https://10.0.1.1/client/api"; final play.libs.F.Promise resultPromise = WS.url(feedUrl).get().map( new Function() { public Result apply(WS.Response response) { return ok("Feed title:" + response.asJson().findPath("title").toString()); } } ); return resultPromise; } 

它在日志中抛出以下错误,

 [error] play - Cannot invoke the action, eventually got an error: java.net.ConnectException: General SSLEngine problem to https://10.0.1.1/client/api [error] application - ! @6fpimpnp6 - Internal server error, for (GET) [/webcall] -> play.api.Application$$anon$1: Execution exception[[ConnectException: General SSLEngine problem to https://10.0.1.1/client/api]] at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10.jar:2.2.0] at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10.jar:2.2.0] at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$2$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:261) [play_2.10.jar:2.2.0] at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$2$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:261) [play_2.10.jar:2.2.0] at scala.Option.map(Option.scala:145) [scala-library.jar:na] at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$2.applyOrElse(PlayDefaultUpstreamHandler.scala:261) [play_2.10.jar:2.2.0] java.net.ConnectException: General SSLEngine problem to https://10.0.1.1/client/api at com.ning.http.client.providers.netty.NettyConnectListener.operationComplete(NettyConnectListener.java:103) ~[async-http-client.jar:na] at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:427) ~[netty.jar:na] at org.jboss.netty.channel.DefaultChannelFuture.notifyListeners(DefaultChannelFuture.java:413) ~[netty.jar:na] at org.jboss.netty.channel.DefaultChannelFuture.setFailure(DefaultChannelFuture.java:380) ~[netty.jar:na] at org.jboss.netty.handler.ssl.SslHandler.setHandshakeFailure(SslHandler.java:1417) ~[netty.jar:na] at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1293) ~[netty.jar:na] Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1362) ~[na:1.7.0_40] at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513) ~[na:1.7.0_40] at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:790) ~[na:1.7.0_40] at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:758) ~[na:1.7.0_40] at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[na:1.7.0_40] at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1225) ~[netty.jar:na] Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.7.0_40] at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1683) ~[na:1.7.0_40] at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:278) ~[na:1.7.0_40] at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) ~[na:1.7.0_40] at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) ~[na:1.7.0_40] at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) ~[na:1.7.0_40] 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:385) ~[na:1.7.0_40] at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.7.0_40] at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.7.0_40] at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) ~[na:1.7.0_40] at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:283) ~[na:1.7.0_40] at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:138) ~[na:1.7.0_40] Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) ~[na:1.7.0_40] at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) ~[na:1.7.0_40] at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ~[na:1.7.0_40] at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.7.0_40] at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.7.0_40] at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) ~[na:1.7.0_40] 

如果我使用HttpsURLConnection调用该服务,它的工作正常,通过添加

 TrustManager[] trustAllcerts = new TrustManager[]{ new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } }}; javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL"); sc.init(null, trustAllcerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HostnameVerifier allHostsValid = new HostnameVerifier() { @Override public boolean verify(String arg0, SSLSession arg1) { // TODO Auto-generated method stub return false; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); 

如何信任 Play Framework中所有自签名 / 不受信任的 ssl证书?

尝试将以下代码添加到conf/application.conf文件中

 ws.acceptAnyCertificate=true 

如果您使用Promise类,这将有效。 但是,如果您通过其他HttpClients调用该服务,则无效。

更新 :从Play Framework 2.5开始,您应该使用以下内容 –

 play.ws.ssl.loose.acceptAnyCertificate=true 

您可以在开发环境中执行此操作,但是您不应该在生产环境中执行此操作,因为它可以certificate是一种安全威胁。 在生产中,而是在密钥库中安装客户端的证书。

请不要接受所有证书 – 您可以将信任管理器与自定义证书一起使用,然后再回到默认信任库。

 ws.ssl { trustManager = { stores = [ { path: ${store.directory}/exampletrust.jks } # Added trust store { path: ${java.home}/lib/security/cacerts } # Fallback to default JSSE trust store ] } } 

有关详细信息,请参阅http://www.playframework.com/documentation/2.3.x/ExampleSSLConfig 。

只需在信任库中安装您想要信任的证书即可。

不要盲目接受所有证书。 这使您的应用程序容易受到MITM攻击。

即使只是为了开发,这是人们在截止日期间忘记删除的那种代码和设置。

您可能遇到的下一个问题是主机名匹配。 您使用的是https://10.0.1.1/的IP地址,因此您的证书应该具有此IP地址的SAN条目,而不仅仅是其CN中的IP地址。 更多细节在这里 。 不要使用您在代码中设置的HostnameVerifier (出于同样的原因)。

您可以尝试设置这些参数

 -Dmail.smtp.ssl.trust=* -Dmail.smtp.ssl.checkserveridentity=false 

在启动你的应用程序时 以下是所有参数的列表: https : //javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html