Using certification as .pem and private key as .key to call secured rest end point in java

375 views Asked by At

I have received the certification as .pem and the private key as .key and the host as wildcard *.domain:* and used them in postman and worked as expected.

Click here for the image

I need to do the same in java , I have tried all the possible scenario I found in the internet like : converting the file using openssl to different formats (cer ,cert,p12,jks) all the scenarios of using keystore and truststore or custom one but, no luck at all Always get:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path >building failed: sun.security.provider.certpath.SunCertPathBuilderException: >unable to find valid certification path to requested target

3

There are 3 answers

2
Phanindra Gopishetty On

create a keystore with .pem and .key file

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.security.KeyStore;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() throws Exception {
        return new RestTemplate(clientHttpRequestFactory());
    }

    private ClientHttpRequestFactory clientHttpRequestFactory() throws Exception {
        return new HttpComponentsClientHttpRequestFactory(httpClient());
    }

    private HttpClient httpClient() throws Exception {
        return HttpClients.custom()
                .setSSLContext(sslContext())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
    }

    private SSLContext sslContext() throws Exception {
        return SSLContextBuilder
                .create()
                .loadKeyMaterial(keyStore(), "your_keystore_password".toCharArray())
                .build();
    }

    private KeyStore keyStore() throws Exception {
        try (InputStream keyStoreInputStream = getClass().getClassLoader().getResourceAsStream("keystore.p12")) {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(keyStoreInputStream, "your_keystore_password".toCharArray());
            return keyStore;
        }
    }
}
0
Phanindra Gopishetty On
    import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.*;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() throws Exception {
        return new RestTemplate(clientHttpRequestFactory());
    }

    private ClientHttpRequestFactory clientHttpRequestFactory() throws Exception {
        return new HttpsClientRequestFactory(sslContext());
    }

    private SSLContext sslContext() throws Exception {
        KeyManager[] keyManagers = getKeyManagers("path/to/your.pem", "path/to/your.key", "your_key_password");
        TrustManager[] trustManagers = getTrustManagers("path/to/server-certificate.pem");

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagers, trustManagers, new SecureRandom());

        return sslContext;
    }

    private KeyManager[] getKeyManagers(String pemFilePath, String keyFilePath, String keyPassword) throws Exception {
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        try (FileInputStream keyInputStream = new FileInputStream(keyFilePath)) {
            keyStore.load(keyInputStream, keyPassword.toCharArray());
        }

        keyManagerFactory.init(keyStore, keyPassword.toCharArray());

        return keyManagerFactory.getKeyManagers();
    }

    private TrustManager[] getTrustManagers(String serverCertificatePath) throws Exception {
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());

        try (FileInputStream serverCertInputStream = new FileInputStream(serverCertificatePath)) {
            trustStore.load(serverCertInputStream, null);
        }

        trustManagerFactory.init(trustStore);

        return trustManagerFactory.getTrustManagers();
    }

    private static class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
        private final SSLContext sslContext;

        public HttpsClientRequestFactory(SSLContext sslContext) {
            this.sslContext = sslContext;
        }

        @Override
        protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
            if (connection instanceof HttpsURLConnection) {
                ((HttpsURLConnection) connection).setSSLSocketFactory(sslContext.getSocketFactory());
            }
            super.prepareConnection(connection, httpMethod);
        }
    }
}
0
Phanindra Gopishetty On

Using .crt and .key file

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

@Configuration
public class RestClientConfig {

    @Bean
    public RestTemplate restTemplate() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException {
        return new RestTemplate(clientHttpRequestFactory());
    }

    private ClientHttpRequestFactory clientHttpRequestFactory() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException {
        SSLContext sslContext = SSLContextBuilder
                .create()
                .loadKeyMaterial(loadKeyStoreFromCrtAndKey("path/to/your/certificate.crt", "path/to/your/keyfile.key"), "your-key-password".toCharArray())
                .loadTrustMaterial(new TrustSelfSignedStrategy())
                .build();

        HttpClient httpClient = HttpClients.custom()
                .setSSLContext(sslContext)
                .build();

        return new HttpComponentsClientHttpRequestFactory(httpClient);
    }

    private KeyStore loadKeyStoreFromCrtAndKey(String certificatePath, String keyPath) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, InvalidKeySpecException {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);  // Initialize an empty keystore

        try (InputStream certInput = new FileInputStream(certificatePath);
             InputStream keyInput = new FileInputStream(keyPath)) {

            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certInput);

            // Load private key from PEM file
            PrivateKey privateKey = readPrivateKeyFromKeyFile(keyInput);

            // Load certificate into the keystore
            keyStore.setCertificateEntry("certificate", cert);

            // Load private key into the keystore
            keyStore.setKeyEntry("private-key", privateKey, "your-key-password".toCharArray(), new java.security.cert.Certificate[]{cert});
        }

        return keyStore;
    }

    private PrivateKey readPrivateKeyFromKeyFile(InputStream keyInput) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        try (PEMParser pemParser = new PEMParser(new InputStreamReader(keyInput))) {
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
            Object keyObject = pemParser.readObject();
            if (keyObject instanceof PEMKeyPair) {
                return converter.getPrivateKey(((PEMKeyPair) keyObject).getPrivateKeyInfo());
            } else {
                throw new IOException("Invalid private key format in key file");
            }
        }
    }
}