Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40); [server #8 @75efdde5] found no selectable cipher suite among the 59 offered #2034

Open
ghettosamson opened this issue Mar 19, 2025 · 0 comments

Comments

@ghettosamson
Copy link

Version Keycloak 26.1.0 in Docker I am using BouncyCastle for my Keycloak in FIPS strict mode. I copy the BouncyCastle jars like so into my Image

# Need to download the fips jars for fips mode
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bc-fips-1.0.2.5.jar > /tmp/bc-fips-1.0.2.5.jar
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bctls-fips-1.0.19.jar > /tmp/bctls-fips-1.0.19.jar
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bcpkix-fips-1.0.7.jar > /tmp/bcpkix-fips-1.0.7.jar
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bcutil-fips-2.0.3.jar > /tmp/bcutil-fips-2.0.3.jar

From my Firefox browser I am able to connect to my Keycloak Admin portal. I don't manually create a p12 keystore or truststore, I just specify the certificate file and the private key file via the following environment variables, KC_HTTPS_CERTIFICATE_KEY_FILE and KC_HTTPS_CERTIFICATE_FILE. I have a NodeJs service running inside a Node 22.14-alpine3.21 Docker container. This service is our API and we have an Angular application that communicates with it. It reaches out to Keycloak for authentication. It is failing to connect to Keycloak and I see the following error on Keycloak:

2025-03-19 21:40:54,111 INFO  [org.bouncycastle.jsse.provider.ProvTlsServer] (vert.x-eventloop-thread-1) [server #8 @75efdde5] raised fatal(2) handshake_failure(40) alert: Failed to process record: org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40); [server #8 @75efdde5] found no selectable cipher suite among the 59 offered: [{0x13,0x02}(TLS_AES_256_GCM_SHA384), {0x13,0x03}(TLS_CHACHA20_POLY1305_SHA256), {0x13,0x01}(TLS_AES_128_GCM_SHA256), {0xc0,0x2f}(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), {0xc0,0x2b}(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), {0xc0,0x30}(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384), {0xc0,0x2c}(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384), {0x00,0x9e}(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), {0xc0,0x27}(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), {0x00,0x67}(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256), {0xc0,0x28}(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384), {0x00,0x6b}(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), {0x00,0xa3}(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384), {0x00,0x9f}(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384), {0xcc,0xa9}(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256), {0xcc,0xa8}(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256), {0xcc,0xaa}(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256), {0xc0,0xaf}(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8), {0xc0,0xad}(TLS_ECDHE_ECDSA_WITH_AES_256_CCM), {0xc0,0xa3}(TLS_DHE_RSA_WITH_AES_256_CCM_8), {0xc0,0x9f}(TLS_DHE_RSA_WITH_AES_256_CCM), {0xc0,0x5d}(TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384), {0xc0,0x61}(TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384), {0xc0,0x57}(TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384), {0xc0,0x53}(TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384), {0x00,0xa2}(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256), {0xc0,0xae}(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8), {0xc0,0xac}(TLS_ECDHE_ECDSA_WITH_AES_128_CCM), {0xc0,0xa2}(TLS_DHE_RSA_WITH_AES_128_CCM_8), {0xc0,0x9e}(TLS_DHE_RSA_WITH_AES_128_CCM), {0xc0,0x5c}(TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256), {0xc0,0x60}(TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256), {0xc0,0x56}(TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256), {0xc0,0x52}(TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256), {0xc0,0x24}(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384), {0x00,0x6a}(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256), {0xc0,0x23}(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), {0x00,0x40}(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256), {0xc0,0x0a}(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), {0xc0,0x14}(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), {0x00,0x39}(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), {0x00,0x38}(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), {0xc0,0x09}(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), {0xc0,0x13}(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), {0x00,0x33}(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), {0x00,0x32}(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), {0x00,0x9d}(TLS_RSA_WITH_AES_256_GCM_SHA384), {0xc0,0xa1}(TLS_RSA_WITH_AES_256_CCM_8), {0xc0,0x9d}(TLS_RSA_WITH_AES_256_CCM), {0xc0,0x51}(TLS_RSA_WITH_ARIA_256_GCM_SHA384), {0x00,0x9c}(TLS_RSA_WITH_AES_128_GCM_SHA256), {0xc0,0xa0}(TLS_RSA_WITH_AES_128_CCM_8), {0xc0,0x9c}(TLS_RSA_WITH_AES_128_CCM), {0xc0,0x50}(TLS_RSA_WITH_ARIA_128_GCM_SHA256), {0x00,0x3d}(TLS_RSA_WITH_AES_256_CBC_SHA256), {0x00,0x3c}(TLS_RSA_WITH_AES_128_CBC_SHA256), {0x00,0x35}(TLS_RSA_WITH_AES_256_CBC_SHA), {0x00,0x2f}(TLS_RSA_WITH_AES_128_CBC_SHA), {0x00,0xff}(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)]
	at org.bouncycastle.tls.AbstractTlsServer.getSelectedCipherSuite(AbstractTlsServer.java:484)
	at org.bouncycastle.jsse.provider.ProvTlsServer.getSelectedCipherSuite(ProvTlsServer.java:618)
	at org.bouncycastle.tls.TlsServerProtocol.generate13ServerHello(TlsServerProtocol.java:286)
	at org.bouncycastle.tls.TlsServerProtocol.generateServerHello(TlsServerProtocol.java:534)
	at org.bouncycastle.tls.TlsServerProtocol.handleHandshakeMessage(TlsServerProtocol.java:1064)
	at org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(TlsProtocol.java:715)
	at org.bouncycastle.tls.TlsProtocol.processRecord(TlsProtocol.java:591)
	at org.bouncycastle.tls.RecordStream.readFullRecord(RecordStream.java:209)
	at org.bouncycastle.tls.TlsProtocol.safeReadFullRecord(TlsProtocol.java:926)
	at org.bouncycastle.tls.TlsProtocol.offerInput(TlsProtocol.java:1368)
	at org.bouncycastle.jsse.provider.ProvSSLEngine.unwrap(ProvSSLEngine.java:486)
	at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:679)
	at io.netty.handler.ssl.JdkSslEngine.unwrap(JdkSslEngine.java:92)
	at io.netty.handler.ssl.JdkAlpnSslEngine.unwrap(JdkAlpnSslEngine.java:163)
	at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:308)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1443)
	at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1336)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1385)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Is there something I have to do to configure the allowed ciphers? I've looked in /usr/share/crypto-policies/policies/FIPS.pol but I don't want to touch files without knowing what I am doing. When a coworker tries to access the Keycloak admin console with Brave Browser, we get the same error. What I don't understand is how this was working before. The only change that I've made to our Keycloak setup is we switched from an Entrust certificate to a Sectigo certificate. Now a whole host of problems is popping up. Below is my Dockerfile

FROM registry.access.redhat.com/ubi9:9.4 AS ubi-micro-build

RUN mkdir -p /mnt/rootfs
RUN dnf install --installroot /mnt/rootfs curl --releasever 9 --setopt install_weak_deps=false --nodocs -y && \
    dnf --installroot /mnt/rootfs clean all && \
    rpm --root /mnt/rootfs -e --nodeps setup

# Need to download the fips jars for fips mode
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bc-fips-1.0.2.5.jar > /tmp/bc-fips-1.0.2.5.jar
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bctls-fips-1.0.19.jar > /tmp/bctls-fips-1.0.19.jar
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bcpkix-fips-1.0.7.jar > /tmp/bcpkix-fips-1.0.7.jar
RUN curl -ksSL https://downloads.bouncycastle.org/fips-java/bcutil-fips-2.0.3.jar > /tmp/bcutil-fips-2.0.3.jar

# Intermediate Build Image -------------------------------------------------------------------------------------
FROM quay.io/keycloak/keycloak:26.1.0 AS builder

ARG DEPLOY_ENV=qa

COPY themes/risc /opt/keycloak/themes/risc
COPY plugins/*.jar /opt/keycloak/providers
COPY ${DEPLOY_ENV}-keycloak.conf /opt/keycloak/conf/keycloak.conf

WORKDIR /opt/keycloak

COPY --from=ubi-micro-build /tmp/*.jar /opt/keycloak/providers/
COPY kc.java.security /opt/keycloak/conf/

# Java security files
COPY java.txt /usr/share/crypto-policies/DEFAULT/java.txt
COPY fips.java.txt /usr/share/crypto-policies/FIPS/java.txt
COPY future.java.txt /usr/share/crypto-policies/FUTURE/java.txt

RUN JAVA_OPTS=-Xmx64g /opt/keycloak/bin/kc.sh build --features=fips --fips-mode=strict


# Final Image -------------------------------------------------------------------------------------
FROM quay.io/keycloak/keycloak:26.1.0 AS final

COPY --from=builder /opt/keycloak /opt/keycloak
COPY --from=ubi-micro-build /mnt/rootfs /

# Java security files
COPY java.txt /usr/share/crypto-policies/DEFAULT/java.txt
COPY fips.java.txt /usr/share/crypto-policies/FIPS/java.txt
COPY future.java.txt /usr/share/crypto-policies/FUTURE/java.txt

# 9000 is for the health endpoints
EXPOSE 8443 9000

ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start", "--spi-password-hashing-pbkdf2-sha256-max-padding-length=14",  "--optimized", "-Djavax.net.debug=ssl"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant