2015-11-03 46 views
3

我有私鑰和服務器證書的陪同證書。 我可以使用捲曲執行它,所有作品都可以。Rest模板與證書

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

但我想用它與java,最好從春天RestTemplate。

回答

4

所以知識關於使用RestTemplate使用Pem證書是分心的。

步驟,而且必須做到:

  1. 添加服務器證書信任庫使用密鑰工具,否則portecle。當你想使用自定義信託使用這個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()); 
    } 
    
    } 
    

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)); 
} 

最後,你可以使用注入restTemplate連接到URL。

+0

它看起來很有用,但你能展示如何使用'RestTemplate'代碼?謝謝 – BSeitkazin