我无法使用pem在resttemplate中设置证书

时间:2017-07-06 11:48:08

标签: java spring ssl resttemplate client-certificates

我的springboot项目有问题。 我必须向其他服务器发送休息呼叫(https:/// ....)。 而且我还必须在java中使用cert key(.pem文件)。

当我在linux服务器(ubuntu)中使用curl命令时,我可以获得成功响应。

curl -X GET --cert <pem file path>:<password> https://<serverurl>:4443

但我的问题是我必须在Springboot java项目中使用RestTemplate。 所以我尝试配置几步,但我失败了。

有没有人知道在resttemplate中使用config cert(pem)?

我的RestTemplateConfig是

@Configuration
public class RestTemplateConfig {
private static Logger logger = LoggerFactory.getLogger(RestTemplateConfig.class);

@Autowired
private Environment env;
// .crt path
@Value("${cert.path}")
private String certFile;
// .p12 path
@Value("${bixby.reward.p12.path}")
private String p12File;
// .jks path
@Value("${http.client.ssl.trust-store}")
private Resource trustStore;
//password
@Value("${http.client.ssl.trust-store-password}")
private char[] trustStorePassword;

@Bean
public RestTemplate restTemplate() {        
    PoolingHttpClientConnectionManager cm = getConnectionManager(2000);

    CloseableHttpClient httpClient = HttpClients.custom()
            .setConnectionManager(cm)
            .setProxy(getProxyHost())
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();

    HttpComponentsClientHttpRequestFactory componentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();

    componentsClientHttpRequestFactory.setHttpClient(httpClient);
    componentsClientHttpRequestFactory.setConnectTimeout(Constants.CONNECTION_TIME_OUT);
    componentsClientHttpRequestFactory.setReadTimeout(Constants.READ_TIME_OUT);

    RestTemplate restTemplate = new RestTemplate(componentsClientHttpRequestFactory);

    return restTemplate;
}

private HttpHost getProxyHost() {
    HttpHost proxyHost = null;

    String httpProxy = env.getProperty("http_proxy");

    if(httpProxy != null) {
        try {
            String host = null;
            int port = -1;

            httpProxy = httpProxy.replace("https://", "").replace("http://", "");
            String [] proxy = httpProxy.split(":");

            host = proxy[0];
            if(proxy.length == 1) {
                port = 80;
            } else {
                port = Integer.parseInt(proxy[1]);
            }

            proxyHost = new HttpHost(host, port);
        } catch(Exception e) {              
            logger.error("[IMPLICIT_ERROR] RestTemplate proxy setting error.", e);
        }
    }       

    return proxyHost;
}

private SSLConnectionSocketFactory getSSLSocketFactoryForNoVerification() {
    SSLConnectionSocketFactory scsf = null; 

    try {
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        File f= new File("");
        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial(null, acceptingTrustStrategy)
                .build();

        scsf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
    } catch (Exception e) {
        logger.error("[IMPLICIT_ERROR] RestTemplate ssl connection socket factory setting error.", e);
    }   

    return scsf;
}

private SSLSocketFactory getSSLSocketFactory() {
    SSLContext sslContext = null;

    try {
        InputStream certInputStream = new FileInputStream(certFile);
        byte[] certAndKey = ByteStreams.toByteArray(certInputStream);
        byte[] certBytes = parseDERFromCert(certAndKey, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----");
        X509Certificate cert = generateCertificateFromDER(certBytes);

        // private key
        KeyStore pkeyStore = KeyStore.getInstance("PKCS12");
        pkeyStore.load(new FileInputStream(p12File), trustStorePassword.toCharArray());
        // "server" is alias
        Key pvtKey = pkeyStore.getKey("server", trustStorePassword.toCharArray());
        java.security.cert.Certificate[] keychain = pkeyStore.getCertificateChain("server");
        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(null);
        keystore.setCertificateEntry("cert-alias", cert);
        keystore.setKeyEntry("key-alias", pvtKey, "changeit".toCharArray(), keychain);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(keystore, "changeit".toCharArray());

        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        sslContext = SSLContexts.custom().loadTrustMaterial(keystore, acceptingTrustStrategy).build();

        KeyManager[] km = kmf.getKeyManagers();
        sslContext.init(km, null, null);
    } catch (Exception e) {
        logger.error("[IMPLICIT_ERROR] RestTemplate ssl connection socket factory setting error.", e);
    }

    return sslContext.getSocketFactory();
}


private PoolingHttpClientConnectionManager getConnectionManager(int maxTotal) {     
    SSLContext sslContext;
    Registry<ConnectionSocketFactory> registry = null;
    try {
        sslContext = SSLContexts
                .custom()
                .loadTrustMaterial(trustStore.getFile(),
                        trustStorePassword)
                .build();

    // Since only our own certs are trusted, hostname verification is probably safe to bypass
        HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.getDefaultHostnameVerifier();
    SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);//new NoopHostnameVerifier());

    registry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", new PlainConnectionSocketFactory())
            //.register("https", getSSLSocketFactoryForNoVerification())
            //.register("https", new SSLConnectionSocketFactory(getSSLSocketFactory(), new NoopHostnameVerifier()))
            .register("https", sslSocketFactory)
            .build();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
    cm.setMaxTotal(maxTotal);
    cm.setDefaultMaxPerRoute(maxTotal);
    return cm;
}

private byte[] parseDERFromCert(byte[] cert, String beginDelimiter, String endDelimiter) {
    String data = new String(cert);
    String[] tokens = data.split(beginDelimiter);
    tokens = tokens[1].split(endDelimiter);

    return DatatypeConverter.parseBase64Binary(tokens[0]);
}

private X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException {
    CertificateFactory factory = CertificateFactory.getInstance("X.509");
    return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes));
}}

0 个答案:

没有答案