Home > other >  How to configure Web client for Https request
How to configure Web client for Https request

Time:09-05

I am trying to understand how to configure the Web client. What I have is a working curl that I am not able to convert into a valid HTTPS request through (any) Java HTTP client. The curl is:

curl -s --cert $CERTIFICATE --key $KEY https.url

where $CERTIFICATE is a .crt file containing:

----BEGIN CERTIFICATE----
....
----END CERTIFICATE-----

And the $KEY is a .key file containing:

-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

I want to convert this curl into a valid JAVA request. Currently, I am configuring a Spring WebClient in this way:

private WebClient getWebClient() throws SSLException {
  SslContext sslContext = SslContextBuilder.forClient().keyManager(
                Paths.get(properties.getCrtFile()).toFile(),
                Paths.get(properties.getKeyFile()).toFile(),
                properties.getCertKeyPassword()).build();

  HttpClient httpClient = HttpClient.create().secure(t -> t.sslContext(sslContext));

  return WebClient
                .builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient)).build();

}

But when I use the webclient to make a request it returns an error:

exception: File does not contain valid private key: 

Any idea where is the error?

CodePudding user response:

This is how I solved the problem:

  1. Verify that .cert and .key files are valid:
openssl x509 -noout -modulus -in certFile.crt | openssl md5
#> (stdin)= 7f1a9c4d13aeaddd77fd4a0f241a6ce8

and

openssl rsa -noout -modulus -in certKey.key | openssl md5
#> (stdin)= 7f1a9c4d13aeaddd77fd4a0f241a6ce8
  1. Convert my .cert and .key files into a PCKS12 that Java can understand. (Keep in mind that my cert and key files are in PEM format as explained in the question). I used the following command:
openssl pkcs12 -export -in certFile.crt -inkey keyFile.key -out cert.p12

This step will prompt you to enter a password. We will use this password when reading the certificate into a KeyStore.

  1. Create an SSLContext by reading the certificate:
private SslContext getSSLContext() {
  try (FileInputStream keyStoreFileInputStream = new 
    FileInputStream("pathTop12CertificateFile")) {
      KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
      keyStore.load(keyStoreFileInputStream,"password".toCharArray());
      KeyManagerFactory keyManagerFactory = 
              KeyManagerFactory.getInstance("SunX509");
      keyManagerFactory.init(keyStore, "password".toCharArray());

      return SslContextBuilder.forClient()
              .keyManager(keyManagerFactory)
              .build();

  } catch (Exception e) {
      log.error("An error has occurred: ", e);
  }
  return null;
}
  1. Build a Spring WebClient using this SSLContext:
private WebClient getWebClient() {
    HttpClient httpClient = HttpClient.create().secure(sslSpec -> sslSpec.sslContext(getSSLContext()));
    ClientHttpConnector clientHttpConnector = new ReactorClientHttpConnector(httpClient);
    return WebClient
            .builder()
            .clientConnector(clientHttpConnector)
            .build();

}

Now we can use WebClient to make our HTTP Requests.

CodePudding user response:

From the details you provided, I understand that the SslContextBuilder can't understand your key type.

Try to convert a non-encrypted key to PKCS8 using the following command.

openssl pkcs8 -topk8 -nocrypt -in pkcs1_key_file -out pkcs8_key.pem

Also, see the examples at https://netty.io/4.0/api/io/netty/handler/ssl/util/InsecureTrustManagerFactory.html that accepts without verification all X.509 certificates, including those that are self-signed.

Also discussed at https://groups.google.com/forum/#!topic/grpc-io/5uAK5c9rTHw

  • Related