akka-http icon indicating copy to clipboard operation
akka-http copied to clipboard

How to skip cert validation with akka client?

Open hatharom opened this issue 4 years ago • 8 comments

I just want to get a 'curl --insecure' like solution

akka-http version: 10.2.4

The 'solution' from the official doc just doesn't work: https://doc.akka.io/docs/akka-http/current/client-side/client-https-support.html#disabling-hostname-verification


  def createInsecureSslEngine(host: String, port: Int): SSLEngine = {
    val engine = SSLContext.getDefault.createSSLEngine(host, port)
    engine.setUseClientMode(true)
    engine
  }
    val badCtx = ConnectionContext.httpsClient(createInsecureSslEngine _)
    val res = Http().outgoingConnectionHttps("localhost",4443, connectionContext = badCtx)
    val response = Await.result(Source.single(Get(url)).via(res).runWith(Sink.head), 60 seconds)
    val responseString =Await.result(Unmarshal(response).to[String], 60 seconds)
    println(responseString)

result: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

hatharom avatar Feb 21 '22 18:02 hatharom

I think you have to include the engine.setSSLParameters (etc) part as well that is commented out in the docs.

raboof avatar Feb 22 '22 14:02 raboof

No, it doesn't work.

 def createInsecureSslEngine(host: String, port: Int): SSLEngine = {
    val engine = SSLContext.getDefault.createSSLEngine(host, port)
    engine.setUseClientMode(true)
    engine.setSSLParameters({
      val params = engine.getSSLParameters
      params.setEndpointIdentificationAlgorithm("https")
      params})
    engine
  }

Why would?

The documentation states above the setSSLParameters part: " // Disabling host name verification is a very bad idea, please don't unless you have a very good reason to. // When in doubt, use the ConnectionContext.httpsClient that takes an SSLContext instead , or enable with: "

So basically it says by providing the sslparameters the host name verification will be enabled

So please reopen

hatharom avatar Feb 22 '22 15:02 hatharom

doh, I read that wrong, sorry

raboof avatar Feb 22 '22 15:02 raboof

So with the change from that section of the docs, Akka HTTP still checks the other side presented a valid certificate, it just no longer checks that certificate belongs to the hostname you think you're connecting to. What you want is to configure it to even accept certificates that are entirely invalid.

Perhaps using an SSLContext like in https://www.javacodemonk.com/allow-insecure-ssl-in-java-11-httpclient-6e677c76 instead of SSLContext.getDefault would work for that?

raboof avatar Feb 22 '22 15:02 raboof

I tried to wire in a custom SSLContext without any success , see here: https://stackoverflow.com/questions/71210533/akka-http-trust-all-certs

Also tried this using the deprecated way : https://gist.github.com/iRevive/7d17144284a7a2227487635ec815860d

The server I communicate towards has a cert which not signed by a CA and I don't have that cert in advance to able to trust on it.

Most of the time it is not a big deal to configure it correctly. For example:

java(apache):

    private HttpClient autoTrustClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
        return HttpClients.custom().setSSLSocketFactory(csf).build();
    }

scalaj library: val res = Http(url).option(HttpOptions.allowUnsafeSSL).asString

Akka-http: Seems impossible after hours of struggling

hatharom avatar Feb 22 '22 15:02 hatharom

I tried to wire in a custom SSLContext without any success , see here: https://stackoverflow.com/questions/71210533/akka-http-trust-all-certs

I answered there. You had a field ordering problem in your attempt to pass in a custom SSLContext.

raboof avatar Feb 22 '22 16:02 raboof

Thanks it works! A bit cumbersome to setup though..

hatharom avatar Feb 23 '22 08:02 hatharom

https://github.com/raboof/akka-http-connect-without-checking-cert/blob/0ca55a06afb83b587f592dd97358970502f7b834/Main.scala - yeah, I see what you mean.

Of course shipping a trustfulSslContext would make things a lot shorter, but we'd have to give it a really scary name to avoid people 'accidentally' throwing security out of the window.

In any case we should document this at https://doc.akka.io/docs/akka-http/current/client-side/client-https-support.html

raboof avatar Feb 23 '22 08:02 raboof