RestTemplate与pem证书

我有私钥和服务器证书的pem证书。 我可以使用curl执行它,一切正常。

curl -O -k --cert-type pem --cert mypem.pem url 

但是我希望将它与java一起使用,最好是从Spring开始使用RestTemplate。

因此,关于在RestTemplate中使用pem证书的知识会分散注意力。

必须采取的步骤:

  1. 使用keytool或portecle将服务器证书添加到trustStore。 如果要使用自定义信任库,请使用此脚本

  2. 接下来将ssl配置为RestTemplate。 它可以像下面这样做:

     @Configuration public class SSLConfiguration { @Value("${certificate.name}") private String name; @Bean(name = "sslContext") public SSLContext sslContext() throws Exception { Security.addProvider(new BouncyCastleProvider()); return SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).useTLS().build(); } @Bean(name = "sslSocketFactory") public SSLSocketFactory sslSocketFactory() throws Exception { return new ConnectionFactoryCreator(name, sslContext()).getSocketFactory(); } @Bean(name = "httpClient") public HttpClient httpClient() throws Exception { return HttpClientBuilder.create().setSslcontext(sslContext()) .setSSLSocketFactory(new SSLConnectionSocketFactory(sslSocketFactory(), new AllowAllHostnameVerifier())) .build(); } @Bean public ClientHttpRequestFactory httpClientRequestFactory() throws Exception { return new HttpComponentsClientHttpRequestFactory(httpClient()); } @Bean public RestTemplate restTemplate() throws Exception { return new RestTemplate(httpClientRequestFactory()); } } 

 public class ConnectionFactoryCreator { private final String pemName; private final SSLContext context; public ConnectionFactoryCreator(String pemName, SSLContext context) { this.pemName = pemName; this.context = context; } public SSLSocketFactory getSocketFactory() throws Exception { InputStream resourceAsStream = getClass().getResourceAsStream(pemName); byte[] certAndKey = ByteStreams.toByteArray(resourceAsStream); byte[] certBytes = parseDERFromPEM(certAndKey, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----"); byte[] keyBytes = parseDERFromPEM(certAndKey, "-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----"); X509Certificate cert = generateCertificateFromDER(certBytes); PrivateKey key = generatePrivateKeyFromDER(keyBytes); KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(null); keystore.setCertificateEntry("cert-alias", cert); keystore.setKeyEntry("key-alias", key, "changeit".toCharArray(), new Certificate[] { cert }); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(keystore, "changeit".toCharArray()); KeyManager[] km = kmf.getKeyManagers(); context.init(km, null, null); return context.getSocketFactory(); } private byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) { String data = new String(pem); String[] tokens = data.split(beginDelimiter); tokens = tokens[1].split(endDelimiter); return DatatypeConverter.parseBase64Binary(tokens[0]); } private PrivateKey generatePrivateKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException { PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory factory = KeyFactory.getInstance("RSA"); return factory.generatePrivate(spec); } private X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException { CertificateFactory factory = CertificateFactory.getInstance("X.509"); return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes)); } 

最后,您可以使用inject restTemplate连接到url。

您需要在Java信任库中导入证书。

BTW pem和cer(t)文件是相同的,只是扩展名的不同名称

其他链接