Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我可以';nt使用pem在resttemplate中设置证书_Java_Spring_Ssl_Resttemplate_Client Certificates - Fatal编程技术网

Java 我可以';nt使用pem在resttemplate中设置证书

Java 我可以';nt使用pem在resttemplate中设置证书,java,spring,ssl,resttemplate,client-certificates,Java,Spring,Ssl,Resttemplate,Client Certificates,我的springboot项目有问题。 我必须向其他服务器发送rest调用(https:///....). 我还必须在java中使用证书密钥(.pem文件) 当我在linux服务器(ubuntu)中使用curl命令时,我可以得到成功响应 curl -X GET --cert <pem file path>:<password> https://<serverurl>:4443 curl-xget--cert:https://:4443 但我的问题是我必须在S

我的springboot项目有问题。 我必须向其他服务器发送rest调用(https:///....). 我还必须在java中使用证书密钥(.pem文件)

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

curl -X GET --cert <pem file path>:<password> https://<serverurl>:4443
curl-xget--cert:https://:4443
但我的问题是我必须在SpringBootJava项目中使用RestTemplate。 因此,我尝试配置一些步骤,但失败了

有人知道在resttemplate中使用配置证书(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));
}}
@配置
公共类RestTemplateConfig{
私有静态记录器Logger=LoggerFactory.getLogger(restemplateconfig.class);
@自动连线
私人环境署;
//.crt路径
@值(${cert.path}”)
私有字符串证书文件;
//.p12路径
@值(${bixby.reward.p12.path})
私有字符串p12文件;
//.jks径
@值(${http.client.ssl.trust store}”)
私有资源信任库;
//密码
@值(${http.client.ssl.trust-store-password}”)
私有字符[]信任存储密码;
@豆子
公共RestTemplate RestTemplate(){
PoollightTPClientConnectionManager cm=getConnectionManager(2000);
CloseableHttpClient httpClient=HttpClients.custom()
.setConnectionManager(cm)
.setProxy(getProxyHost())
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
HttpComponents客户端HttpRequestFactory组件客户端HttpRequestFactory=新的HttpComponents客户端HttpRequestFactory();
组件客户端HttpRequestFactory.setHttpClient(httpClient);
componentsClientHttpRequestFactory.setConnectTimeout(常数.CONNECTION\u TIME\u OUT);
ComponentClientHttpRequestFactory.setReadTimeout(常数.READ\u TIME\u OUT);
RestTemplate RestTemplate=新的RestTemplate(ComponentClientHttpRequestFactory);
返回REST模板;
}
私有HttpHost getProxyHost(){
HttpHost proxyHost=null;
字符串httpProxy=env.getProperty(“http_proxy”);
if(httpProxy!=null){
试一试{
字符串host=null;
int端口=-1;
httpProxy=httpProxy.replace(“https://”和“”).replace(“http://”和“”);
字符串[]proxy=httpProxy.split(“:”);
主机=代理[0];
如果(proxy.length==1){
端口=80;
}否则{
port=Integer.parseInt(代理[1]);
}
proxyHost=新的HttpHost(主机、端口);
}捕获(例外e){
logger.error(“[隐式错误]RestTemplate代理设置错误”,e);
}
}       
返回代理主机;
}
私有SSLConnectionSocketFactory getSSLSocketFactoryForNoVerification(){
SSLConnectionSocketFactory scsf=null;
试一试{
TrustStrategy acceptingTrustStrategy=(X509Certificate[]链,字符串authType)->true;
文件f=新文件(“”);
SSLContext SSLContext=SSLContexts.custom()
.loadTrustMaterial(空,acceptingTrustStrategy)
.build();
scsf=新的SSLConnectionSocketFactory(sslContext,新的NoopHostnameVerifier());
}捕获(例外e){
logger.error(“[隐式错误]RestTemplate ssl连接套接字工厂设置错误”,e);
}   
返回scsf;
}
私有SSLSocketFactory getSSLSocketFactory(){
SSLContext SSLContext=null;
试一试{
InputStream certInputStream=新文件InputStream(certFile);
字节[]certAndKey=ByTestStreams.toByteArray(certInputStream);
byte[]certBytes=parseDERFromCert(certAndKey,“----开始证书----”,“----结束证书----”;
X509Certificate cert=generateCertificateFromDER(certBytes);
//私钥
KeyStore pkeyStore=KeyStore.getInstance(“PKCS12”);
load(新文件输入流(p12文件)、trustStorePassword.toCharray());
//“服务器”是别名
Key pvtKey=pkeyStore.getKey(“服务器”,trustStorePassword.tocharray());
java.security.cert.Certificate[]keychain=pkeyStore.getCertificateChain(“服务器”);
KeyStore KeyStore=KeyStore.getInstance(“JKS”);
keystore.load(null);
setCertificateEntry(“证书别名”,cert);
setKeyEntry(“密钥别名”,pvtKey,“changeit”.toCharArray(),keychain);
KeyManagerFactory kmf=KeyManagerFactory.getInstance(“SunX509”);
init(密钥库,“changeit.tocharray());
TrustStrategy acceptingTrustStrategy=(X509Certificate[]链,字符串authType)->true;
sslContext=SSLContexts.custom().loadTrustMaterial(密钥库,acceptingTrustStrategy.build();
KeyManager[]km=kmf.getKeyManager();
init(km,null,null);
}捕获(例外e){
logger.error(“[隐式错误]RestTemplate ssl连接套接字工厂设置错误”,e);
}
返回sslContext.getSocketFactory();
}
专用池TpClientConnectionManager getConnectionManager(int maxTotal){
SSLContext SSLContext;
注册表=空;
试一试{
sslContext=SSLContexts
.custom()
.loadTrustMaterial(trustStore.getFile(),
TrustStore(密码)
.build();
//因为只有我们自己的证书是可信的,所以主机名验证可能是安全的
HostnameVerifier HostnameVerifier=SSLConnectionSocketFactory.getDefaultHostnameVerifier();
SSLConnectionSocketFactory sslSocketFactory=新的SSLConnectionSocketFactory(sslContext,hostnameVerifier);//新的NoopHostnameVerifier();
registry=RegistryBuilder.create()
.register(“http”,新的PlainConnectionSocketFactory())
//.register(“https”,getSSLSocketFactoryForNoVerification())
//.register(“https”、新的SSLConnectionSocketFactory(getSSLSocketFactory()、新的NoopHostnameVerifier()))
.register(“https”,sslSocketFactory)
.build();
}捕获(例外e){
//托德