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

如何解决SpringBoot双向SSL认证报Received fatal alert: bad_certificate错误

SpringBoot服务双向SSL认证握手失败问题解决方案

本地搭建两个SpringBoot服务配置双向SSL认证时,完成常规配置后接口调用抛出SSL握手异常,以下是完整问题场景及解决方法:

常规配置步骤

  • 分别为服务端、客户端生成JKS格式密钥库,使用keytool命令操作
  • 导出双方X.509格式证书,分别导入对方的信任库中实现证书互信,对应操作均使用keytool命令完成
  • 分别配置服务端、客户端的application.properties参数:开启SSL、配置密钥库与信任库的路径、密码、类型,服务端额外设置server.ssl.client-auth=need强制校验客户端证书
  • 客户端与服务端的启动类均通过@Value注解读取SSL配置,写入javax.net.ssl相关系统属性
  • 客户端通过默认初始化的RestTemplate调用服务端HTTPS接口时触发异常:
    • 客户端报错:javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
    • 服务端报错:javax.net.ssl.SSLHandshakeException: Empty client certificate chain

解决方案

默认初始化的RestTemplate不会加载自定义的密钥库、信任库配置,导致请求时未携带客户端证书,触发校验失败。需要自定义配置绑定了对应SSL上下文的RestTemplate,参考配置代码如下:

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Value;
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.security.KeyStore;

@Configuration
public class SslRestTemplateConfig {

    @Value("${server.ssl.key-store}")
    private String keyStorePath;
    @Value("${server.ssl.key-store-password}")
    private String keyStorePass;
    @Value("${server.ssl.trust-store}")
    private String trustStorePath;
    @Value("${server.ssl.trust-store-password}")
    private String trustStorePass;

    @Bean
    public RestTemplate sslRestTemplate() throws Exception {
        // 加载客户端密钥库
        KeyStore keyStore = KeyStore.getInstance("JKS");
        try (FileInputStream ksIs = new FileInputStream(keyStorePath)) {
            keyStore.load(ksIs, keyStorePass.toCharArray());
        }
        // 加载客户端信任库
        KeyStore trustStore = KeyStore.getInstance("JKS");
        try (FileInputStream tsIs = new FileInputStream(trustStorePath)) {
            trustStore.load(tsIs, trustStorePass.toCharArray());
        }
        // 构建适配双向认证的SSL上下文
        SSLContext sslContext = SSLContextBuilder.create()
                .loadKeyMaterial(keyStore, keyStorePass.toCharArray())
                .loadTrustMaterial(trustStore, null)
                .build();
        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(socketFactory)
                .build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(requestFactory);
    }
}

后续业务代码中直接注入该sslRestTemplate实例发起HTTPS请求,即可正常完成双向SSL校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:39:02