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

Spring MVC中使用双向SSL证书调用API的Java示例求助

双向SSL认证REST API调用Spring MVC实现示例

前置证书格式转换

Java原生KeyStore仅支持JKS/PKCS12格式的密钥库,你需要先把手中的证书文件转换为对应格式:

  • 生成服务端信任库truststore:将服务端公共证书public.cer导入信任库,用于后续校验服务端身份
    执行命令:
    keytool -import -alias server-public-cert -file public.cer -keystore truststore.jks -storetype JKS
    
    执行过程中按提示设置信任库密码即可
  • 生成客户端密钥库keystore:将客户端私有证书sslclient.private转为PKCS12格式密钥库,private.passphrase中存储的是客户端私钥的解锁口令,转换时需要用到
    执行命令:
    openssl pkcs12 -export -inkey sslclient.private -in sslclient.crt -name client-auth-cert -out client-keystore.p12 -passin file:private.passphrase
    
    若你没有单独的客户端公钥证书sslclient.crt,可确认sslclient.private是否包含完整证书链,直接替换上述命令的输入文件路径即可

依赖引入(Maven示例)

你需要引入Apache HttpClient依赖用于构建支持SSL的请求客户端,Spring MVC项目默认已包含spring-web依赖无需额外引入:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

RestTemplate SSL配置类实现

我们通过配置类自定义支持双向SSL的RestTemplate实例,后续直接注入该实例即可调用双向认证接口:

import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;

@Configuration
public class SslRestTemplateConfig {

    // 可将以下配置项放到application.properties中通过@Value注入,避免硬编码
    private static final String KEYSTORE_PATH = "你的client-keystore.p12文件路径";
    private static final String TRUSTSTORE_PATH = "你的truststore.jks文件路径";
    private static final String PASSPHRASE_FILE_PATH = "你的private.passphrase文件路径";
    private static final String TRUSTSTORE_PASSWORD = "你生成truststore时设置的密码";

    @Bean
    public RestTemplate sslRestTemplate() throws Exception {
        // 读取私钥口令
        String clientKeyPass = Files.readAllLines(Paths.get(PASSPHRASE_FILE_PATH)).get(0).trim();

        // 加载客户端密钥库
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        try (FileInputStream keystoreIs = new FileInputStream(KEYSTORE_PATH)) {
            keyStore.load(keystoreIs, clientKeyPass.toCharArray());
        }

        // 加载服务端信任库
        KeyStore trustStore = KeyStore.getInstance("JKS");
        try (FileInputStream truststoreIs = new FileInputStream(TRUSTSTORE_PATH)) {
            trustStore.load(truststoreIs, TRUSTSTORE_PASSWORD.toCharArray());
        }

        // 构建SSL上下文
        SSLContext sslContext = SSLContextBuilder.create()
                .loadKeyMaterial(keyStore, clientKeyPass.toCharArray())
                .loadTrustMaterial(trustStore, null)
                .build();

        // 构建支持SSL的HttpClient
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLContext(sslContext)
                .build();

        // 生成RestTemplate实例
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        // 可选配置超时时间
        requestFactory.setConnectTimeout(5000);
        requestFactory.setReadTimeout(10000);

        return new RestTemplate(requestFactory);
    }
}

接口调用示例

直接注入上述配置好的sslRestTemplate即可发起双向SSL认证的接口请求,和普通RestTemplate用法完全一致:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestController {

    @Autowired
    private RestTemplate sslRestTemplate;

    @GetMapping("/test-ssl-api")
    public String testTwoWaySslApi() {
        String targetApiUrl = "双向认证接口的目标地址";
        // 调用GET接口示例
        return sslRestTemplate.getForObject(targetApiUrl, String.class);
    }
}

注意事项

  • 生产环境不要把证书密码、文件路径硬编码到代码中,建议放到配置中心或加密配置文件中
  • 证书文件建议放到项目resources目录下,通过ResourceUtils.getFile("classpath:xxx.jks")方式加载,避免绝对路径适配问题
  • 如果调用接口出现证书校验错误,可先确认导入到truststore中的public.cer是否是目标服务端的根证书或站点证书

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:54:06