带有 PEM 证书和私钥的 RestTemplate

问题描述 投票:0回答:1

我在从 SpringBoot RestTemplate 连接到 HTTPS 服务器时遇到问题。服务器团队为我提供了 pem 证书 (.pem) 和私钥 (.key)。我需要配置我的 spring 服务以使用我拥有的证书和密钥通过 https 连接。

我所做的是:

1- 将 .pem 文件和 .key 文件合并到一个 .pem 文件中,并确认我有 -----BEGIN CERTIFICATE----- 和 -----BEGIN RSA PRIVATE KEY-----在组合 pem 中:

cat server-cert.pem server-private-key.key > combined-cert-and-key.pem

2- 创建 JKS 密钥库和信任库并向其中添加证书:

keytool -genkeypair -alias dev -keyalg RSA -keysize 2048 -dname "CN=Preview,OU=B,O=Company,L=City,S=ON,C=CA" -keypass PASSWROD -keystore dev.jks -storepass PASSWROD -validity 3650
keytool -importcert -keystore dev.jks -alias dev1-public-cert -file combined-cert-and-key.pem -storepass PASSWROD -noprompt

3- 将我的 JKS 导出为 base64(因为我需要这样做,所以我可以通过重建 JKS 从我的配置服务器加载文件)

openssl base64 -in dev.jks -out dev.txt

4-休息控制器:

    @Autowired
    private RestTemplate rest;

    @RequestMapping(value = "/search", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> searchCreditCard(@RequestHeader(value = "Authorization", required = true) String authorization,
        @RequestBody Object bod) {

    String firstDataUrl = String.format("%s", "https://SERVER-DOMAIN/search");
    HttpHeaders header = new HttpHeaders();
    header.set("Content-Type", "application/json");
    HttpEntity<Object> httpEntity = new HttpEntity<>(bod, header);

    Object response = rest.postForEntity(firstDataUrl, httpEntity, Object.class);
    return new ResponseEntity<>(response, HttpStatus.OK);
    }

5-应用程序.java:

@Value("${tls.keystore.value}")
private String keyStoreValue; // the base64 of my keystore created from #3

@Value("${tls.keystore.password}")
private String keyStorePass;

@Value("${tls.truststore.value}")
private String trustStoreValue; // the base64 of my keystore created from #3

@Value("${tls.truststore.password}")
private String trustStorePass;


@Bean
public RestTemplate template() throws KeyManagementException, NoSuchAlgorithmException {
return new RestTemplate(new HttpComponentsClientHttpRequestFactory(getHttpClient()));
}

private HttpClient getHttpClient() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = buildSSLContext(keyStoreValue, keyStorePass, trustStoreValue, trustStorePass);
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext);
return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
}

@SuppressWarnings("unused")
private static SSLContext buildSSLContext(String keyStoreValue, String keyStorePass, String trustStoreValue,
    String trustStorePass) {
KeyStore keyStore = loadJksKeyStore(keyStoreValue, keyStorePass);
KeyStore trustStore = loadJksKeyStore(trustStoreValue, trustStorePass);

return buildSSLContext(keyStore, trustStore, keyStorePass.toCharArray());
}

@SuppressWarnings("deprecation")
private static SSLContext buildSSLContext(KeyStore keyStore, KeyStore trustStore, char[] keyPassword) {
try {
    return SSLContexts.custom().loadTrustMaterial(trustStore, TrustSelfSignedStrategy.INSTANCE)
        .loadKeyMaterial(keyStore, keyPassword).build();
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
    throw new RuntimeException("Cloud not setup SSLContext", e);
}
}

private static KeyStore loadJksKeyStore(String based64Value, String password) {
byte[] jksFile = Base64.getMimeDecoder().decode(based64Value);

return loadJksKeyStore(new ByteArrayInputStream(jksFile), password);
}

private static KeyStore loadJksKeyStore(InputStream inputStream, String password) {
try {
    KeyStore keyStore = KeyStore.getInstance("JKS");
    char[] passwordAsCharArray = password == null ? null : password.toCharArray();
    keyStore.load(inputStream, passwordAsCharArray);
    return keyStore;
} catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException e) {
    throw new RuntimeException("Unable to load JKS KeyStore", e);
}
}

但是,我仍然收到此错误:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
spring-boot ssl spring-security resttemplate
1个回答
0
投票

我仍然面临同样的问题,你解决了这个问题吗??

© www.soinside.com 2019 - 2024. All rights reserved.