相关文章推荐
失眠的芹菜  ·  【2020.8】【EMUI ...·  4 月前    · 
刚失恋的烤面包  ·  DataSet (Flink : ...·  10 月前    · 
追风的打火机  ·  BBA真得小心了 ...·  1 年前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account Handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40) #1156 Handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40) #1156 zxcvbnmlkjh opened this issue Apr 24, 2022 · 10 comments

@peterdettman Peter I am sharing all the detail, please help. Thanks

I am setting these Java options

export _JAVA_OPTIONS="-Djdk.tls.trustNameService=true -Dorg.bouncycastle.jca.enable_jks=true -Djava.security.debug=provider -Djava.security.properties==/Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/jre/lib/security/java.security.bcfips -Dorg.bouncycastle.fips.approved_only=true"

Changing these properties in JAVA.security file

security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=sun.security.provider.Sun

These are my jar versions.

bc-fips-1.0.2.1.jar
bcpkix-fips-1.0.5.jar
bctls-fips-1.0.12.1.jar
[bcmail-fips-1.0.3.jar

We are trying to connect to audit-publish service

https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting

This is full stack trace

Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [o.b.jsse.provider.ProvTlsClient: INFO ] - Client raised fatal(2) handshake_failure(40) alert: Failed to read record
org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:846)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(TlsProtocol.java:416)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:86)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:445)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:426)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:361)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckBase.checkHealth(HealthCheckBase.java:47)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckAuditService.checkHealth(HealthCheckAuditService.java:31)
at com.sap.ariba.security.file.fortification.service.monitoring.MasterHealthMetricsReporter.lambda$bindTo$1(MasterHealthMetricsReporter.java:98)
at io.micrometer.statsd.StatsdGauge.value(StatsdGauge.java:49)
at io.micrometer.statsd.StatsdGauge.poll(StatsdGauge.java:54)
at io.micrometer.statsd.StatsdMeterRegistry.poll(StatsdMeterRegistry.java:178)
at io.micrometer.statsd.StatsdMeterRegistry.lambda$startPolling$13(StatsdMeterRegistry.java:295)
at io.micrometer.shaded.reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onNext(FluxDoOnEach.java:140)
at io.micrometer.shaded.reactor.core.publisher.FluxInterval$IntervalRunnable.run(FluxInterval.java:123)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.call(PeriodicWorkerTask.java:59)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.run(PeriodicWorkerTask.java:73)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [c.s.a.s.f.f.s.m.m.HealthCheckBase: ERROR] - Health Check: service at URL https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting responded with message I/O error on GET request for " https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting ": handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
Provider: SecureRandom.null algorithm from: BCFIPS_RNG
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS

We need more information to help you. What version of BC jars are you using? Do you have a full stack trace for the exception? What system are you trying to make a TLS connection to?

@peterdettman Peter I am sharing all the detail, please help. Thanks

I am setting these Java options

export _JAVA_OPTIONS="-Djdk.tls.trustNameService=true -Dorg.bouncycastle.jca.enable_jks=true -Djava.security.debug=provider -Djava.security.properties==/Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/jre/lib/security/java.security.bcfips -Dorg.bouncycastle.fips.approved_only=true"

Changing these properties in JAVA.security file

security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=sun.security.provider.Sun

These are my jar versions.

bc-fips-1.0.2.1.jar
bcpkix-fips-1.0.5.jar
bctls-fips-1.0.12.1.jar
[bcmail-fips-1.0.3.jar

We are trying to connect to audit-publish service

https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting

This is full stack trace

Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [o.b.jsse.provider.ProvTlsClient: INFO ] - Client raised fatal(2) handshake_failure(40) alert: Failed to read record
org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:846)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(TlsProtocol.java:416)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:86)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:445)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:426)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:361)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckBase.checkHealth(HealthCheckBase.java:47)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckAuditService.checkHealth(HealthCheckAuditService.java:31)
at com.sap.ariba.security.file.fortification.service.monitoring.MasterHealthMetricsReporter.lambda$bindTo$1(MasterHealthMetricsReporter.java:98)
at io.micrometer.statsd.StatsdGauge.value(StatsdGauge.java:49)
at io.micrometer.statsd.StatsdGauge.poll(StatsdGauge.java:54)
at io.micrometer.statsd.StatsdMeterRegistry.poll(StatsdMeterRegistry.java:178)
at io.micrometer.statsd.StatsdMeterRegistry.lambda$startPolling$13(StatsdMeterRegistry.java:295)
at io.micrometer.shaded.reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onNext(FluxDoOnEach.java:140)
at io.micrometer.shaded.reactor.core.publisher.FluxInterval$IntervalRunnable.run(FluxInterval.java:123)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.call(PeriodicWorkerTask.java:59)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.run(PeriodicWorkerTask.java:73)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [c.s.a.s.f.f.s.m.m.HealthCheckBase: ERROR] - Health Check: service at URL https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting responded with message I/O error on GET request for " https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting ": handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
Provider: SecureRandom.null algorithm from: BCFIPS_RNG
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS

This exception happens when the server simply closes the connection before the handshake has completed. It means that you would need to look at the server logs in order to know the reason for the failure. If the server logs aren't accessible, you could get a packet capture of the connection attempt using e.g. Wireshark and we might be able to see something obvious.

It might also be worth trying with the latest available FIPS jars (at least we can rule out already-fixed bugs):

bc-fips-1.0.2.3.jar
bcmail-fips-1.0.4.jar
bcpkix-fips-1.0.6.jar
bctls-fips-1.0.13.jar

This exception happens when the server simply closes the connection before the handshake has completed. It means that you would need to look at the server logs in order to know the reason for the failure. If the server logs aren't accessible, you could get a packet capture of the connection attempt using e.g. Wireshark and we might be able to see something obvious.

It might also be worth trying with the latest available FIPS jars (at least we can rule out already-fixed bugs):

bc-fips-1.0.2.3.jar bcmail-fips-1.0.4.jar bcpkix-fips-1.0.6.jar bctls-fips-1.0.13.jar

@peterdettman Peter

 public double checkHealth (final String healthCheckServiceUrl)
 final RestTemplate restTemplate = new RestTemplate();
    try {
        final ResponseEntity<String> responseEntity =
                restTemplate.getForEntity(healthCheckServiceUrl, String.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            log.debug("Health Check: service Running at URL {} is up", healthCheckServiceUrl);
            return SERVICE_UP;

I had this code which was creating issue, When i changed this Code to this it worked,

  public double checkHealth (final String healthCheckServiceUrl)
    final HttpClient client = HttpClients.createDefault();
    final ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(client);
    final RestTemplate restTemplate = new RestTemplate(factory);
    try {
        final ResponseEntity<String> responseEntity =
                restTemplate.getForEntity(healthCheckServiceUrl, String.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            log.debug("Health Check: service Running at URL {} is up", healthCheckServiceUrl);
            return SERVICE_UP;

When I am using HttpClient to make Https call it works and when it uses HttpsUrlConnection it throws me handshake failure, Is it the expected behaviour of HttpsUrlConnection with BCFIPS? Please provide your thoughts on it.

The two code examples look the same to me. Do you mean that you changed the URL from http to https?

HTTP doesn't use TLS at all, so it doesn't have much to do with this issue. The question is why the TLS connection fails and from what I can see the error happens at the server.

Do you know of any other client software that is able to make an HTTPS connection to this same server?

The two code examples look the same to me. Do you mean that you changed the URL from http to https?

HTTP doesn't use TLS at all, so it doesn't have much to do with this issue. The question is why the TLS connection fails and from what I can see the error happens at the server.

Do you know of any other client software that is able to make an HTTPS connection to this same server?

@peterdettman Sorry Peter i updated the above answer, two codes are now different, Can you check now.

The HTTP connection doesn't use TLS, and the HTTPS connection does use TLS, but gets the handshake_failure exception. The TLS connection happens (and fails) before any request is sent, so the error has nothing to do with the application traffic (HTTP).

Do you have other software that can connect to the HTTPS URL?

The HTTP connection doesn't use TLS, and the HTTPS connection does use TLS, but gets the handshake_failure exception. The TLS connection happens (and fails) before any request is sent, so the error has nothing to do with the application traffic (HTTP).

Do you have other software that can connect to the HTTPS URL?

My current service makes an outbound TLS connection to AuditPublish service to check the status of this service using this url https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting". For which I am getting Handshake failure. This is the code for the Https call.

     public double checkHealth (final String healthCheckServiceUrl)
     final RestTemplate restTemplate = new RestTemplate();
        try {
            final ResponseEntity<String> responseEntity =
                    restTemplate.getForEntity(healthCheckServiceUrl, String.class);
            if (responseEntity.getStatusCode() == HttpStatus.OK) {
                log.debug("Health Check: service Running at URL {} is up", healthCheckServiceUrl);
                return SERVICE_UP;
          

I think im seeing this exact same issue. My keycloak has an auditlog .jar deployed which makes HTTPS requests. We have 2 requests happening -- one to our AuthZ server to get an access token, another to actually POST to auditlog (behind apigateway). The call to AuthZ goes through perfectly (not hosted on AWS infra), but when we try to hit auditlog, we see handshake_failed(40) with no other informative errors. Seems like this handshake_failed is due to client/server not agreeing on terms of connection. I have forced TLSv1.2, so im sure keycloak is using it for the AuthZ call and the Auditlog call.