RDS for PostgreSQL でポスト量子 TLS 鍵交換を試してみた
はじめに
2026年9月24日、Amazon RDS for PostgreSQL が TLS のポスト量子鍵交換に対応しました。
Aurora MySQL のポスト量子鍵交換は、先行記事で紹介しています。
RDS for PostgreSQL も対応したので、OpenSSL と JDK 27(Corretto 27)から接続して鍵交換グループを確認しました。Corretto 27 側のポスト量子 TLS 対応は次の記事で扱っています。
検証環境
| 項目 | 値 |
|---|---|
| RDS エンジン | PostgreSQL 18.6 |
| 接続元 EC2 | Amazon Linux 2023(aarch64) |
| OpenSSL(接続元 EC2) | 3.5.8 |
| JDK | Amazon Corretto 27 |
| PostgreSQL JDBC ドライバ | 42.7.7 |
| リージョン | ap-northeast-1 |
ssl_groups に X25519MLKEM768 を設定する
対象の DB インスタンスには、あらかじめ作成したパラメータグループ pq-tls-pg18 を適用しています。このパラメータグループの ssl_groups に、ポスト量子グループ X25519MLKEM768 を設定しました。
aws rds modify-db-parameter-group \
--db-parameter-group-name pq-tls-pg18 \
--parameters "ParameterName=ssl_groups,ParameterValue=X25519MLKEM768,ApplyMethod=immediate" \
--region ap-northeast-1
設定後の値と、指定できる値(AllowedValues)は次のとおりです。
[
{
"ParameterName": "ssl_groups",
"ParameterValue": "X25519MLKEM768",
"Description": "Sets the named group(s) to use for TLS key exchange",
"Source": "user",
"ApplyType": "dynamic",
"DataType": "list",
"AllowedValues": "X25519MLKEM768, SecP256r1MLKEM768, X25519, prime256v1, secp384r1",
"IsModifiable": true,
"ApplyMethod": "immediate"
}
]
指定できるのは AllowedValues にあるグループのみです。今回はポスト量子鍵交換を確認するため X25519MLKEM768 のみを設定しました。
OpenSSL で接続して鍵交換グループを確認する
接続元 EC2 から s_client で接続しました。
echo "" | openssl s_client \
-connect pq-tls-pg18.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:5432 \
-starttls postgres \
-tls1_3 \
-groups X25519MLKEM768:x25519:prime256v1 \
-trace 2>&1
出力のうち、鍵交換グループ・暗号スイート・プロトコルの行だけ抜き出すと次のとおりです。
Negotiated TLS1.3 group: X25519MLKEM768
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
ssl_groups に設定した X25519MLKEM768 で鍵交換が成立しました。
Corretto 27 の JDBC 接続で確認する
次に、接続元 EC2 上の Docker コンテナで動かした Corretto 27 から JDBC で接続しました。接続プロパティはユーザー、パスワード、ssl、sslmode だけで、鍵交換グループは指定していません(コードは節末尾に置いています)。ハンドシェイクのログは -Djavax.net.debug=ssl:handshake で採りました。
ClientHello の supported_groups は次の並びでした。
"supported_groups (10)": {
"named groups": [X25519MLKEM768, x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096]
}
アプリ側で何も指定していなくても、X25519MLKEM768 が先頭に来ています。これに対してサーバーが返した ServerHello の key_share も X25519MLKEM768 でした。
"key_share (51)": {
"server_share": {
"named group": X25519MLKEM768
プロトコルは TLS 1.3 です。
Negotiated protocol version: TLSv1.3
サーバーが許す唯一のグループである X25519MLKEM768 で、JDBC からも接続できました。
接続に使った Dockerfile・Java コードと実行手順
Dockerfile
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 TARGETARCH
RUN case "${TARGETARCH}" in \
amd64) JDK_URL="https://corretto.aws/downloads/latest/amazon-corretto-27-x64-linux-jdk.tar.gz" ;; \
arm64) JDK_URL="https://corretto.aws/downloads/latest/amazon-corretto-27-aarch64-linux-jdk.tar.gz" ;; \
*) echo "Unsupported arch: ${TARGETARCH}" && exit 1 ;; \
esac \
&& curl -fsSL "${JDK_URL}" | tar -xz -C /opt \
&& ln -s /opt/amazon-corretto-27* /opt/java
ENV JAVA_HOME=/opt/java
ENV PATH="${JAVA_HOME}/bin:${PATH}"
WORKDIR /app
ADD https://repo1.maven.org/maven2/org/postgresql/postgresql/42.7.7/postgresql-42.7.7.jar /app/postgresql.jar
COPY PgTlsCheck.java .
RUN javac -cp postgresql.jar PgTlsCheck.java
CMD ["java", \
"-Djavax.net.debug=ssl:handshake", \
"-cp", ".:postgresql.jar", \
"PgTlsCheck"]
PgTlsCheck.java
import java.sql.*;
import java.util.Properties;
public class PgTlsCheck {
public static void main(String[] args) throws Exception {
String host = System.getenv("PG_HOST");
String port = System.getenv().getOrDefault("PG_PORT", "5432");
String user = System.getenv().getOrDefault("PG_USER", "pgadmin");
String pass = System.getenv("PG_PASSWORD");
String db = System.getenv().getOrDefault("PG_DB", "postgres");
System.out.println("=== Corretto 27 PQ TLS Check (PostgreSQL) ===");
System.out.println("Target: " + host + ":" + port + "/" + db);
System.out.println("Java version: " + System.getProperty("java.version"));
System.out.println("Java vendor: " + System.getProperty("java.vendor"));
System.out.println();
String url = "jdbc:postgresql://" + host + ":" + port + "/" + db;
Properties props = new Properties();
props.setProperty("user", user);
props.setProperty("password", pass);
props.setProperty("ssl", "true");
props.setProperty("sslmode", "require");
try (Connection conn = DriverManager.getConnection(url, props);
Statement stmt = conn.createStatement()) {
System.out.println("Connected successfully!");
System.out.println();
System.out.println("--- TLS Session Status ---");
try (ResultSet rs = stmt.executeQuery(
"SELECT ssl, version, cipher, bits FROM pg_stat_ssl WHERE pid = pg_backend_pid()")) {
if (rs.next()) {
System.out.println("ssl: " + rs.getBoolean("ssl"));
System.out.println("version: " + rs.getString("version"));
System.out.println("cipher: " + rs.getString("cipher"));
System.out.println("bits: " + rs.getInt("bits"));
}
}
try (ResultSet rs = stmt.executeQuery("SELECT version()")) {
if (rs.next()) System.out.println("PostgreSQL: " + rs.getString(1));
}
}
}
}
ビルドと実行(接続元 EC2 上)
# ビルド
docker build -t pg-pq-tls .
# 実行(-Djavax.net.debug=ssl:handshake は Dockerfile の CMD に含む)
docker run --rm \
-e PG_HOST=pq-tls-pg18.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
-e PG_PASSWORD="$PG_PASSWORD" \
pg-pq-tls
まとめ
RDS for PostgreSQL でポスト量子鍵交換を利用可能なことを確認できました。
2035年までのポスト量子暗号(PQC)移行を目指すガイドライン対応が求められる場合、ポスト量子鍵交換に対応したバージョンの RDS for PostgreSQL を採用し、パラメータグループの ssl_groups にポスト量子グループを設定してご利用ください。








