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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19288803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 15:43:42  来源:igfitidea点击:

Trust all SSL certificates in Java Playframework 2.2

javasslplayframework-2.0ssl-certificate

提问by asvignesh

I am trying to call a web-service(Which has self signed SSL certificate) in Play Framework Using the following function:

我正在尝试使用以下函数在 Play Framework 中调用网络服务(具有自签名 SSL 证书):

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

It is throwing the following Error in Logs,

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

[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: 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$$anonfun$applyOrElse.apply(PlayDefaultUpstreamHandler.scala:261) [play_2.10.jar:2.2.0]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$$anonfun$applyOrElse.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.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]

If I call the service using HttpsURLConnection its working fine by adding

如果我使用 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);

How to Trust all Selfsigned/ Untrustedssl certificates in Play Framework?

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

采纳答案by Rahul Bobhate

Try adding the following code to conf/application.conffile

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

ws.acceptAnyCertificate=true

This will work if you are using the Promiseclass. But won't work if you are calling the service through other HttpClients.

如果您正在使用Promise该类,这将起作用。但如果您通过其他 HttpClient 调用该服务,则将不起作用。

UPDATE: As of Play Framework 2.5, you should use the following -

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

play.ws.ssl.loose.acceptAnyCertificate=true

You can do this in development environment, but you should never do this in Production environment, as it can prove as a security threat. In production, instead install the certificates of the client in your keystore.

您可以在开发环境中执行此操作,但绝不能在生产环境中执行此操作,因为这可能会构成安全威胁。在生产中,改为在您的密钥库中安装客户端的证书。

回答by Bruno

Just install the certificate you're trying to trust in your trust store.

只需在您的信任库中安装您尝试信任的证书。

Don't accept all certificates blindly. This makes your application vulnerable to MITM attacks.

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

Even if it's just for development, that's the kind of code and settings that people forget to remove when it's deadline day.

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

The next problem you might have is host name matching. You're using an IP address in https://10.0.1.1/, so your certificate should have a SAN entry for this IP address, not just that IP address in its CN. More details here. Don't use the HostnameVerifieryou've set up in your code (for the same reasons).

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

回答by Will Sargent

Please don't accept all certificates -- you can use the trust manager with your custom certificates, and then fall back to the default trust store.

请不要接受所有证书——您可以使用带有自定义证书的信任管理器,然后回退到默认信任库。

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

See http://www.playframework.com/documentation/2.3.x/ExampleSSLConfigfor more details.

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

回答by Klapsa2503

You can try to set these parameters

你可以尝试设置这些参数

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

when starting your app. Here is the list of all parameters: https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html

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