RestTemplate与pem证书

时间:2015-11-03 11:22:21

标签: java spring authentication resttemplate pem

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

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

但我想在java中使用它,最好是从Spring开始使用RestTemplate。

2 个答案:

答案 0 :(得分:5)

因此,关于将pem证书与RestTemplate一起使用的知识会分散注意力。

必须采取的步骤:

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

  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());
     }
    
    }
    
  3. 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。

答案 1 :(得分:0)

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

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

其他链接