I tried verifying TLS connections using PQ key exchange supported in Aurora MySQL 8.4.8

I tried verifying TLS connections using PQ key exchange supported in Aurora MySQL 8.4.8

Aurora MySQL 8.4.8 added support for post-quantum cryptography (PQC) hybrid key exchange (PQ key exchange). We verified whether X25519MLKEM768 would be selected during the TLS handshake when connecting from a JDK 27 client where PQ key exchange is enabled by default, or whether additional server-side configuration would be required.
2026.09.07

This page has been translated by machine translation. View original

Introduction

The Aurora MySQL 8.4.8 announced on September 3, 2026 was introduced in a previous article.

https://dev.classmethod.jp/articles/aurora-mysql-848-ga-diff-from-847/

This article covers the PQC support that was mentioned in the previous article as something to be introduced at a later date.

8.4.8 supports X25519MLKEM768 and SecP256r1MLKEM768 as PQC hybrid key exchange in TLS 1.3.

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraMySQLReleaseNotes/AuroraMySQL.Updates.848.html

This time, we connected from a JDK 27 client and verified the key exchange group selected during the TLS handshake.

Verification Details

We placed one EC2 instance (Amazon Linux 2023, ARM64) in the same VPC as Aurora, and connected from a JDK 27 container running on it.

Verification Environment

For verification, we used JDK 27 (build 27+35) before GA, Aurora MySQL 8.4.8, and MySQL Connector/J 9.0.0. The JDK version is as follows.

openjdk version "27" 2026-09-15
OpenJDK Runtime Environment (build 27+35-2325)
OpenJDK 64-Bit Server VM (build 27+35-2325, mixed mode, sharing)

The Aurora version and TLS settings for the connection destination were verified with the following queries.

SELECT VERSION();
SHOW VARIABLES LIKE 'tls%';
SHOW VARIABLES LIKE 'ssl%';
  • VERSION(): 8.4.8
  • tls_version: TLSv1.2,TLSv1.3
  • tls_ciphersuites: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384

No items for enabling or disabling PQ key exchange were found in the tls% and ssl% variables.

Connection Client

The JDK source and Connector/J version are as shown in the Dockerfile.

Dockerfile for JDK 27 client
FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
    curl ca-certificates \
    && rm -rf /var/lib/apt/lists/*

ARG JDK_URL=https://download.java.net/java/GA/jdk27/55ce5470a6294008af0057ff4626d0e5/35/GPL/openjdk-27_linux-aarch64_bin.tar.gz
RUN curl -fsSL ${JDK_URL} | tar -xz -C /opt \
    && ln -s /opt/jdk-27 /opt/java

ENV JAVA_HOME=/opt/java
ENV PATH="${JAVA_HOME}/bin:${PATH}"

WORKDIR /app

ADD https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/9.0.0/mysql-connector-j-9.0.0.jar /app/mysql-connector-j.jar

COPY MysqlTlsTest.java .

RUN javac -cp mysql-connector-j.jar MysqlTlsTest.java

CMD ["java", "-Djavax.net.debug=ssl:handshake", "-cp", ".:mysql-connector-j.jar", "MysqlTlsTest"]

The configuration section of the code used for the connection is as follows. The handshake log obtained with this configuration is from a connection with certificate verification disabled.

String url = String.format("jdbc:mysql://%s:%s/%s", host, port, database);

Properties props = new Properties();
props.setProperty("user", user);
props.setProperty("password", password);
props.setProperty("useSSL", "true");
props.setProperty("requireSSL", "true");
props.setProperty("verifyServerCertificate", "false");

The three SSL-related properties above are deprecated since Connector/J 8. The way to write them when enabling certificate verification will be described later.

The build and execution were performed with the following commands.

docker build -f Dockerfile.jdk27 -t mysql-tls-java-jdk27 java-client/
docker run --rm \
  -e MYSQL_HOST="$MYSQL_HOST" \
  -e MYSQL_PORT=3306 \
  -e MYSQL_USER=admin \
  -e MYSQL_PASSWORD="$MYSQL_PASSWORD" \
  -e MYSQL_DATABASE=mysql \
  mysql-tls-java-jdk27 > jdk27-handshake.log 2>&1

The key exchange group only appears in the handshake log. We ran it with -Djavax.net.debug=ssl:handshake in the Dockerfile's CMD and read the ServerHello from the output log.

Quick Verification with OpenSSL

If you cannot immediately prepare a PQC-compatible JDK, you can first check whether the source OpenSSL has X25519MLKEM768. We ran the following commands on this EC2.

openssl version
openssl list -tls-groups

The OpenSSL version and supported groups were as follows.

OpenSSL 3.5.7 9 Jun 2026 (Library: OpenSSL 3.5.7 9 Jun 2026)
secp256r1:secp384r1:secp521r1:x25519:x448:brainpoolP256r1tls13:brainpoolP384r1tls13:brainpoolP512r1tls13:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192:MLKEM512:MLKEM768:MLKEM1024:SecP256r1MLKEM768:X25519MLKEM768:SecP384r1MLKEM1024

MLKEM-based groups were listed in the latter half of the list, and X25519MLKEM768 was also included. This can be used as a way to first isolate the client-side support status when PQ key exchange does not succeed. However, a group existing in the library and that group being presented and selected during connection are different things. Whether it succeeded or not is read from the handshake log below.

Handshake Verification

The JDK 27 client presented X25519MLKEM768 in the supported_groups of the ClientHello.

    "supported_groups (10)": {
      "named groups": [X25519MLKEM768, x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096]
    },

In the subsequent ServerHello, Aurora selected X25519MLKEM768.

"ServerHello": {
  "server version"      : "TLSv1.2",
  "cipher suite"        : "TLS_AES_256_GCM_SHA384(0x1302)",
  "compression methods" : "00",
  "extensions"          : [
    "key_share (51)": {
      "server_share": {
        "named group": X25519MLKEM768

The key_share in TLS 1.3 is the agreed key exchange group itself. From this "named group": X25519MLKEM768, we can confirm that this group was used by both the server and the client. The server version in the quote is a field that contains TLSv1.2 for compatibility. The actually negotiated version appears in Negotiated protocol version in the log.

javax.net.ssl|DEBUG|30|main|2026-09-07 04:41:02.984 UTC|ServerHello.java:1049|Negotiated protocol version: TLSv1.3

Not only the handshake but also the connection was established, and the cipher suite and TLS version of the session were as follows.

Connected successfully!

=== TLS Session Status ===
Ssl_cipher: TLS_AES_256_GCM_SHA384
Ssl_version: TLSv1.3

Combined Use with Certificate Verification

We verified whether the same group would be selected even with certificate verification enabled.

We set Connector/J's sslMode to VERIFY_IDENTITY, imported the RDS CA bundle into the truststore, and ran it. The bundle used was https://truststore.pki.rds.amazonaws.com/ap-northeast-1/ap-northeast-1-bundle.pem (retrieved on 2026-09-07). The connection properties are as follows.

Properties props = new Properties();
props.setProperty("user", user);
props.setProperty("password", password);
props.setProperty("sslMode", "VERIFY_IDENTITY");
props.setProperty("trustCertificateKeyStoreUrl", "file:/app/rds-truststore.p12");
props.setProperty("trustCertificateKeyStoreType", "PKCS12");
props.setProperty("trustCertificateKeyStorePassword", "changeit");

Even with this configuration, the server_share in ServerHello was the same X25519MLKEM768.

Summary

With Aurora MySQL 8.4.8, which supports PQC key exchange, PQ key exchange was established by making the client PQC-compatible. This was confirmed in the ServerHello of the handshake log.

Government agencies and similar organizations have indicated policies aimed at transitioning to PQC by 2035.

https://www.cyber.go.jp/pdf/press/20251120_PQC_chukantorimatome.pdf

PQ key exchange became available in Aurora MySQL 8.4.8, following MySQL 26.7.0 in July 2026. On the client side, JDK 27, which has PQ key exchange enabled by default, is scheduled to GA on 2026-09-15.

If you plan to adopt Aurora MySQL in the future and there is a possibility of being required to support PQC, we recommend verifying whether PQ key exchange can be used with the combination of Aurora MySQL 8.4.8, PQC-compatible middleware, and JDK.

https://aws.amazon.com/about-aws/whats-new/2026/09/amazon-aurora-mysql-848-available/

https://blogs.oracle.com/mysql/post-quantum-cryptography-support-in-mysql

Share this article

AWSのお困り事はクラスメソッドへ