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

Spring Boot中使用RestTemplate实现带证书的HTTPS调用

用Spring Boot的RestTemplate实现指定HTTPS客户端证书调用

核心配置对应

你要实现的curl命令包含几个关键要求:

  • 强制使用TLSv1.2协议
  • 信任自定义CA证书(对应--cacert参数)
  • 携带客户端证书(对应--cert参数)及PKCS8格式的私钥(对应--key参数)

以下是具体实现步骤:

1. 构建带SSL配置的RestTemplate

需要先加载证书和私钥,生成符合要求的SSLContext,再注入到RestTemplate的请求工厂中:

import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class SslRestTemplateConfig {

    public RestTemplate createSslRestTemplate() throws Exception {
        // 1. 加载CA证书,构建信任库
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        X509Certificate caCert;
        try (FileInputStream fis = new FileInputStream("/etc/pki_service/ca/cacerts.pem")) {
            caCert = (X509Certificate) certFactory.generateCertificate(fis);
        }
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);
        trustStore.setCertificateEntry("ca-trust-cert", caCert);

        // 2. 加载客户端证书
        X509Certificate clientCert;
        try (FileInputStream fis = new FileInputStream("/etc/identity/client/certificates/client.pem")) {
            clientCert = (X509Certificate) certFactory.generateCertificate(fis);
        }

        // 3. 加载PKCS8格式的私钥
        String privateKeyRaw = new String(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get("/etc/identity/client/keys/client-key.pkcs8")))
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s", "");
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyRaw);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);

        // 4. 构建客户端密钥库
        KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        clientKeyStore.load(null, null);
        // 若私钥有密码,替换第三个参数为密码字符数组,比如"your-pass".toCharArray()
        clientKeyStore.setKeyEntry("client-auth-key", privateKey, new char[0], new Certificate[]{clientCert});

        // 5. 生成SSLContext,指定TLSv1.2
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(clientKeyStore, new char[0]);

        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

        // 6. 配置RestTemplate请求工厂
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setSslContext(sslContext);

        return new RestTemplate(requestFactory);
    }
}

2. 注册RestTemplate到Spring容器

在配置类中把上述RestTemplate注册为Bean,方便依赖注入:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate sslRestTemplate() throws Exception {
        return new SslRestTemplateConfig().createSslRestTemplate();
    }
}

3. 使用RestTemplate发起请求

注入配置好的RestTemplate后,即可正常调用目标接口:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class HttpsClient {

    @Autowired
    private RestTemplate sslRestTemplate;

    public String callTargetServer() {
        String targetUrl = "https://server.com";
        return sslRestTemplate.getForObject(targetUrl, String.class);
    }
}

注意事项

  • 确保应用程序对证书、私钥文件有读取权限,否则会抛出IO异常
  • 生产环境建议通过@Value注入文件路径,避免硬编码,比如@Value("${ssl.ca-cert-path}")
  • 若需要连接池、超时等更灵活的配置,可以改用HttpComponentsClientHttpRequestFactory(基于Apache HttpClient),配置逻辑类似

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:52:28