2015-11-03 8 views
3

У меня есть сертификат pem с секретным ключом и сертификатом сервера. Я могу выполнить его с помощью curl, и все работает нормально.RestTemplate с сертификатом pem

Но я хочу использовать его с java, наиболее предпочтительно будет RestTemplate с весны.

ответ

4

Итак, знание об использовании сертификата pem с RestTemplate отвлекается.

шаги, которые должны быть сделаны: сертификат

  1. Добавить сервер в доверенное хранилище, используя Keytool или portecle. Если вы хотите использовать пользовательский trusttore, используйте это значение 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

0

Вам необходимо импортировать сертификат в хранилище доверия java.

BTW PEM и CER (т) файлы одинаковы, просто другое название для расширения

Дополнительные ссылки

+0

Во время импорта у меня есть: keytool error: java.lang.Exception: не входной сертификат X.509 – marok