【问题标题】:SSLHandshakeException: Received fatal alert: access_deniedSSLHandshakeException:收到致命警报:access_denied
【发布时间】:2019-05-28 04:18:15
【问题描述】:

在使用 Spring Boot Rest Template 调用 GET 调用时出现 sslhandshake 异常并出现访问被拒绝错误。

我正在开发一个 java 客户端来从 prometheus 服务器获取指标。 使用 Tls1 ,1.1 和 1.2 创建具有基本身份验证和 sslContext 的 RestTemplate。

但是在调用 GET 调用时出现以下异常。

org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://a5faff994509b11e99f7d0285e129587-2110882066.us-east-1.elb.amazonaws.com/api/v1/query": Received fatal alert: access_denied; nested exception is javax.net.ssl.SSLHandshakeException: Received fatal alert: access_denied
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:311)
    at com.opscx.prometheus.PrometheusPocApplication.main(PrometheusPocApplication.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: access_denied
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:359)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:108)
    at com.opscx.prometheus.BasicAuthInterceptor.intercept(BasicAuthInterceptor.java:35)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:92)
    at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:76)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
    ... 11 more

类 org.springframework.web.client.ResourceAccessException

尝试使用 -Djavax.net.debug=ssl:handshake:verbose 进行调试,但无法解决问题。

这里是调试日志

trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1542173365 bytes = { 177, 65, 144, 227, 154, 51, 246, 129, 182, 251, 188, 204, 134, 212, 156, 222, 208, 90, 86, 46, 87, 105, 16, 134, 146, 83, 144, 225 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension extended_master_secret
Extension server_name, server_name: [type=host_name (0), value=a5faff994509b11e99f7d0285e129587-2110882066.us-east-1.elb.amazonaws.com]
***
main, WRITE: TLSv1.2 Handshake, length = 273
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, access_denied
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: access_denied    

这是我的代码

SSLContext sslContext = null;
        try {
            sslContext = SSLContextBuilder.create()
                    .loadTrustMaterial(null, (chain, authType) -> true)
                    .build();

        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }

        SSLConnectionSocketFactory sslConnectionSocketFactory =
                new SSLConnectionSocketFactory(sslContext,

                        new String[] { "TLSv1","TLSv1.1","TLSv1.2" },
                        //null,
                        null,
                        new LaxHostnameVerifier());

        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
                new PoolingHttpClientConnectionManager(RegistryBuilder.<ConnectionSocketFactory> create()
                        .register("http",
                                PlainConnectionSocketFactory.getSocketFactory())
                        .register("https",
                                sslConnectionSocketFactory)
                        .build());


        CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(poolingHttpClientConnectionManager).build();
        return httpClient;

我正在使用所有三个 TLS 协议创建一个 sslcontext。 调试日志的输出让我感到困惑。

    main, WRITE: TLSv1.2 Handshake, length = 273
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, access_denied

clienthello 是用 TLSV1.2 完成的,为什么会有一个 TLSv1 alert 的 READ 消息?然后奇怪的是 TLSv1.2 ALERT 的 RECV 消息?

如果服务器能够使用 TLSv1.2 发送警报,为什么不接受握手请求?

所有密码套件都已启用,并且它应该同意任何一种密码。双方都有共同的密码。

相同的代码适用于其他基于 REST 的服务器。我通常不会在通话中发送证书,它应该可以工作。

注意:昨晚 IST 使用了相同的代码。奇怪的是,有时有效,有时无效

我在这方面花费了更多时间,但无法获得有关拒绝访问错误的足够答案。如果有人能给我一些关于这方面的见解,那就太好了。

【问题讨论】:

    标签: java spring-boot ssl tls1.2 sslcontext


    【解决方案1】:

    clienthello 是用 TLSV1.2 完成的,为什么会有一个 TLSv1 alert 的 READ 消息?然后奇怪的是 TLSv1.2 ALERT 的 RECV 消息?

    服务器决定它不喜欢这个客户端。来自TLS alwert的描述:

    access_denied
    收到了有效的证书,但是当访问控制被 申请后,发件人决定不进行协商。这个 消息总是致命的。

    因此,您需要与服务器提供商核实服务器对客户端的实际要求。例如,客户端可能需要提供特定的客户端证书,而您没有提供或提供错误的证书。

    【讨论】:

    • 是否应该像我要连接的服务器一样与服务器提供商核实?相同的 GET url 如何与 Chrome 一起使用?我也尝试过使用自我验证的证书。有没有办法调试和理解 chrome 发送到该服务器的证书使其工作?
    • @DeepakSelvakumar:只要还没有使用 TLS 1.3,您就可以从数据包捕获 (Wireshark) 中看到发送了哪些证书。 “相同的 GET url 如何与 Chrome 一起使用?” - 您的问题没有提供任何信息,实际服务器要求是什么以及如何配置 Chrome 以匹配这些,这意味着不知道 Chrome 是什么使服务器接受请求有所不同。
    • Chrome 没有配置任何默认值。打开此 URL 会给出有关证书警告的安全警告。允许继续询问凭据并收到结果。我可以安装wireshark并检查流量、证书等。我应该如何以及寻找什么来检查服务器的要求?谢谢..
    • @DeepakSelvakumar:要获得服务器的要求,您需要询问负责服务器的人员,即他们对可以连接的客户端有什么样的限制。
    • 奇怪的是,GET url 在我的家庭网络中有效,但在其他网络中无效。我尝试使用 Chrome 开发工具比较两个网络中颁发的证书,发现两个证书是相同的。我看到的唯一区别是在家庭网络中,使用的密码不同。它是带有 P-256 和 AES_128_GCM 的 ECDHE_RSA。而在另一个网络中,它是 ECDHE_RSA 和 AES_128_GCM。这有什么区别吗?
    【解决方案2】:

    jlink 生成的JRE 缺少jdk.crypto.ec 模块时,我收到了这个确切的错误消息。

    要包含模块:
    jlink --add-modules jdk.crypto.ec

    Related answer

    【讨论】:

      猜你喜欢
      • 2012-10-15
      • 2018-04-09
      • 2014-03-09
      • 2020-06-07
      • 2016-10-13
      • 1970-01-01
      相关资源
      最近更新 更多