You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 6调用API报SSLPeerUnverifiedException,Java 8正常如何解决?

问题

使用Jersey客户端调用获取Token的API时,Java 8环境下可正常返回响应,但在Java 1.6环境运行时抛出javax.net.ssl.SSLPeerUnverifiedException: 未验证对等方错误。目标API可能运行在Java 8或11环境,更换为Apache HTTP客户端库后问题依旧,需修改代码或配置哪些内容以适配Java 1.6?

原代码

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;

import java.io.IOException;

import static com.oxdeo.serviceclient.constants.*;

public class TokenService {
    protected final Log logger = LogFactory.getLog(TokenService.class);
    private static String bodyStr = "grant_type=client_credentials&client_id=" + coreClientId + "&client_secret=" + coreClientSecret;

    private Client jerseyClient = new Client();

    public String getToken() {
        WebResource webResource = jerseyClient.resource(coreTokenURL);
        ClientResponse clientResponse = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, bodyStr);
        logger.info("client response  token: " + clientResponse.getStatus());
        String token = null;
        if (clientResponse.getStatus() == 200) {
            token = parseToken(clientResponse);
        } else {
            logger.error("Unable to get  token. response:" + clientResponse.getStatus());
        }
        return token;
    }

    private String parseToken(ClientResponse clientResponse) {
        String accessToken="";
        String responseStr = clientResponse.getEntity(String.class);
        JSONObject jsonResponse = new JSONObject(responseStr);
        if(clientResponse.getStatus() >=200 && clientResponse.getStatus()  <=204) {
             accessToken = jsonResponse.getString("access_token");
        }
        return accessToken;
    }

}

错误信息

javax.net.ssl.SSLPeerUnverifiedException: 未验证对等方

解决方案

1. 强制使用Java 1.6兼容的TLS版本

Java 1.6默认仅启用TLS 1.0,而运行在Java 8/11的API可能已禁用该协议版本。需手动指定兼容的TLS版本(若API仍支持TLS 1.0),或安装JDK 1.6的JSSE扩展补丁以支持TLS 1.1/1.2。

2. 导入目标API的根证书到Java 1.6信任库

Java 1.6默认信任库cacerts可能缺少目标API使用的CA根证书,导致SSL验证失败:

  • 导出目标API的SSL证书(可通过浏览器或openssl s_client -connect <域名>:443命令获取)
  • 使用keytool命令将证书导入JDK 1.6的jre/lib/security/cacerts:
    keytool -import -alias <自定义别名> -file <证书路径> -keystore <JDK1.6路径>/jre/lib/security/cacerts
    
    默认信任库密码为changeit。

3. 配置Jersey客户端的自定义SSL上下文

可通过自定义SSL上下文绕过证书验证(仅测试环境使用,生产环境不推荐),或加载自定义信任库,修改后的代码示例:

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.client.urlconnection.HTTPSProperties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;

import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import static com.oxdeo.serviceclient.constants.*;

public class TokenService {
    protected final Log logger = LogFactory.getLog(TokenService.class);
    private static String bodyStr = "grant_type=client_credentials&client_id=" + coreClientId + "&client_secret=" + coreClientSecret;

    private Client jerseyClient;

    public TokenService() {
        this.jerseyClient = createSslEnabledClient();
    }

    private Client createSslEnabledClient() {
        try {
            // 信任所有证书的TrustManager(测试用)
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() { return null; }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {}
                    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {}
                }
            };

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new SecureRandom());

            // 绕过域名验证的HostnameVerifier(测试用)
            HostnameVerifier allHostsValid = (hostname, session) -> true;

            Client client = Client.create();
            HTTPSProperties httpsProperties = new HTTPSProperties(allHostsValid, sslContext);
            client.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, httpsProperties);

            return client;
        } catch (Exception e) {
            logger.error("Failed to create SSL enabled client", e);
            return Client.create();
        }
    }

    public String getToken() {
        WebResource webResource = jerseyClient.resource(coreTokenURL);
        ClientResponse clientResponse = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, bodyStr);
        logger.info("client response  token: " + clientResponse.getStatus());
        String token = null;
        if (clientResponse.getStatus() == 200) {
            token = parseToken(clientResponse);
        } else {
            logger.error("Unable to get token. response:" + clientResponse.getStatus());
        }
        return token;
    }

    private String parseToken(ClientResponse clientResponse) {
        String accessToken="";
        String responseStr = clientResponse.getEntity(String.class);
        JSONObject jsonResponse = new JSONObject(responseStr);
        if(clientResponse.getStatus() >=200 && clientResponse.getStatus()  <=204) {
             accessToken = jsonResponse.getString("access_token");
        }
        return accessToken;
    }

}

4. 安装JDK 1.6的JSSE扩展补丁

Oracle官方为JDK 1.6提供了支持TLS 1.1/1.2的扩展补丁,安装后可让Java 1.6支持更高版本的TLS协议,解决协议版本不兼容导致的SSL验证失败。

内容的提问来源于stack exchange,提问作者ANJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:15:26