Home > Software engineering >  How to import a pem file directly to use with a FeignClient?
How to import a pem file directly to use with a FeignClient?

Time:08-11

I have a client certificate .pem file including private key and certificate. I want to use Feign to call the restful api which requires client certificate.

I googled a lot of examples but those examples teach that import keys from jks like below:

public class App {

    public static void main(String[] args) throws Exception {
        SSLFactory sslFactory = SSLFactory.builder()
                .withIdentityMaterial("identity.jks", "password".toCharArray())
                .withTrustMaterial("truststore.jks", "password".toCharArray())
                .build();

        Feign.Builder client = Feign.builder()
                .client(new Client.Default(sslFactory.getSslSocketFactory(), sslFactory.getHostnameVerifier()));
    }

}

However, I want to import the cert from .pem file directly because I don't have .jks file and don't want convert it by manual because the .pem file is fetched programmatically periodically from other servers. How can I do that?

CodePudding user response:

I am the library maintainer of the SSLFactory which you posted in your question. It is pretty easy to use pem files without converting them to keystore files. You need an extion library to enable that feature. Can you add the following library:

<dependency>
    <groupId>io.github.hakky54</groupId>
    <artifactId>sslcontext-kickstart-for-pem</artifactId>
    <version>7.4.5</version>
</dependency>

After importing the library you can use the following snippet

public class App {

    public static void main(String[] args) throws Exception {
        X509ExtendedKeyManager keyManager = PemUtils.loadIdentityMaterial(Paths.get("/path/to/your/certificate-chain.pem"), Paths.get("/path/to/your/private-key.pem"));
        X509ExtendedTrustManager trustManager = PemUtils.loadTrustMaterial(Paths.get("/path/to/your/some-trusted-certificate.pem"));

        SSLFactory sslFactory = SSLFactory.builder()
                  .withIdentityMaterial(keyManager)
                  .withTrustMaterial(trustManager)
                  .build();

        Feign.Builder client = Feign.builder()
                .client(new Client.Default(sslFactory.getSslSocketFactory(), sslFactory.getHostnameVerifier()));
    }

}

Update

It seems like the OP wants to supply a pem file as identity which contains the certificate chain and private key as a single file. On my initial answer I posted an example where two separate files need to be provided, but a single file is also possible, see here for the example:

X509ExtendedKeyManager keyManager = PemUtils.loadIdentityMaterial(Paths.get("/path/to/your/identity.pem"));

If your private key is encrypted you can provide the password as second parameter as shown below:

X509ExtendedKeyManager keyManager = PemUtils.loadIdentityMaterial(Paths.get("/path/to/your/identity.pem"), "password".toCharArray());

All possible usages can be found in the unit test of the PemUtils here: https://github.com/Hakky54/sslcontext-kickstart/blob/5bcc06a862d654e5e59daa4175c39abe230b8fb6/sslcontext-kickstart-for-pem/src/test/java/nl/altindag/ssl/util/PemUtilsShould.java#L65

  • Related