javax.net.ssl.SSLException: 接收到致命警告:坏的记录MAC

8

我在进行HTTPS连接时,遇到了一个javax.net.ssl.SSLException: Received fatal alert: bad_record_mac的问题。并非每个请求都会出现这个错误,如果我连续发送相同的请求10次,只有一两次会出现此错误。

以下是我用来验证证书的代码:

TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }

        } };

        try {
            SSLContext sslContext = null;
                try {
                    sslContext = SSLContext.getInstance("SSLv3");
                    
                } catch (NoSuchAlgorithmException e3) {
                    logException(Arrays.toString(e3.getStackTrace()));          
            }

            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            SSLSocketFactory factory = sslContext.getSocketFactory();
            HttpsURLConnection.setDefaultSSLSocketFactory(factory);
        } catch (KeyManagementException e) {
            logException(Arrays.toString(e.getStackTrace()));
        }

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        /*
         * end of the fix
         */ 

我在我的主方法中设置了两个系统属性:

System.setProperty("jsse.enableSNIExtension", "false");
        System.setProperty("https.protocols", "SSLv3");

但是什么都没有帮助。

我已经设置了该属性。 - Amith
顺便提一下,如果目标只有一个服务器(即没有具有不同目标的负载均衡器),则它不符合此错误的标准:https://bugs.openjdk.java.net/browse/JDK-4615819(虽然这个问题已经十年了,但客户端方面从未得到修复)。但是我想提及它作为可能出现 SSL3-only 服务器的情况...(这种情况不应再出现!) - eckes
3个回答

5
根据这个rubygems问题和错误的详细描述(见下文),似乎这是Oracle JDK中存在而OpenJDK中不存在的一个bug。我记得(但无法验证)OpenSSL中也存在一个导致此错误的bug,因此您可能需要检查连接另一侧的软件。
您可以在这里阅读更多关于此错误的细节。

我们在使用Braintree的支付网关时遇到了这个问题,他们说将Oracle JDK升级到1.7 u 51或更高版本可以解决这个问题(确实,在u 67中我们不再看到这个问题)。我正在尝试找出JDK的最低版本,因为他们只说了u 45“或更低”... - Sean Corfield

4

很难说是什么原因导致这个问题。您需要通过分析日志来找出原因。设置属性启用调试:

System.setProperty("javax.net.debug", "all");

请检查出现了什么问题。

问题可能是服务器不支持TLS,这可能会被实现所选择。为了确保您始终使用纯粹的SSLv3,请设置以下属性:

System.setProperty("https.protocols", "SSLv3");

2

尝试将com.sun.net.ssl.rsaPreMasterSecretFix设置为true


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接