この記事は「PQC Advent Calendar 2025」の 3 日目です。
※この記事はAIによって生成されたコンテンツを含みます。スクリーンショット、コマンド出力、ログ、トレースなどには含みません。
本記事では、Ubuntu 25.10(questing)上でビルドした OpenSSH v10.2p1 を用いて、
ML-KEM768(NIST PQC Round 3 採択)を組み込んだ PQ/T Hybrid 鍵共有方式(KEX) である mlkem768x25519-sha256 が実際に利用されていることを確認します。
また、Wireshark による SSH_MSG_KEX_HYBRID_INIT / SSH_MSG_KEX_HYBRID_REPLY のパケット解析、さらに PQC 非対応 KEX が選ばれた場合の警告メッセージ についても確認します。
背景
PQC(Post-Quantum Cryptography)導入の流れ
CRQC(Cryptographically Relevant Quantum Compute)が実用化された場合、従来の楕円曲線暗号(ECDH/ECDSA)や DH は破られる可能性があります。そのため SSH/TLS/IKE などの通信プロトコルでは、PQC への移行が進んでいます。
SSH では 2023〜2025 年にかけて PQC 実装が急速に広がり、PQC と従来方式を併用する PQ/T Hybrid 鍵交換(Hybrid KEX) が整備されました。
Internet-Draft の状況
SSH における ML-KEM Hybrid KEX を定義する Internet-Draft は 2025 年 12 月時点でも Active 状態です。
OpenSSH における PQC Hybrid KEX 対応の進化
| Version | 内容 |
|---|---|
| v9.0 |
sntrup761x25519-sha512(@openssh.com) がデフォルト化 |
| v9.9 |
mlkem768x25519-sha256 が追加 |
| v10.0 |
mlkem768x25519-sha256 がデフォルト化 |
| v10.1 | 非 PQC KEX を選択した際に警告メッセージが表示 |
検証環境
OS / OpenSSH
-
OS:Ubuntu 25.10
- UTM 4.7.4
- M1 MacBook Pro (14inch, 2021)
-
OpenSSH:v10.2p1(ビルド)
- Port 10022
OpenSSH v10.2p1 のビルド・インストール
OpenSSH v10.2 をインストールするために、ソースからビルドします。既存の SSH 環境と分離するために Port 10022 を便宜上利用し、念の為、systemctl でシステム・サービス管理しておきます。
sudo apt update
sudo apt install -y build-essential libssl-dev zlib1g-dev
curl -LO https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-10.2p1.tar.gz
tar xzf openssh-10.2p1.tar.gz
cd openssh-10.2p1
./configure \
--prefix=/opt/openssh-10.2 \
--sysconfdir=/opt/openssh-10.2/etc \
--without-pam \
--without-openssl-engine
make -j$(nproc)
sudo make install
sudo tee a.txt <<'EOF'
[Unit]
Description=OpenSSH 10.2 server
After=network.target auditd.service
[Service]
ExecStart=/opt/openssh-10.2/sbin/sshd -D -f /opt/openssh-10.2/etc/sshd_config
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo sed -i '/^#\?Port /d' /opt/openssh-10.2/etc/sshd_config
echo 'Port 10022' | sudo tee -a /opt/openssh-10.2/etc/sshd_config > /dev/null
sudo systemctl daemon-reload
sudo systemctl start sshd-10.2
sudo systemctl enable sshd-10.2
デフォルトで Hybrid KEX が選択されることの確認
接続施行
verbose オプションを付与して、デバッグメッセージが出力されるようにして、SSH 接続します。
/opt/openssh-10.2/bin/ssh localohast -p 10022 -vvv
debug ログ(KexAlgorithms 選択確認)
KEX アルゴリズムとして最終的に mlkem768x25519-sha256 が選ばれたことが debug メッセージから確認できます。
(snip)
debug1: SSH2_MSG_KEXINIT sent
debug3: receive packet: type 20
debug1: SSH2_MSG_KEXINIT received
debug2: local client KEXINIT proposal
debug2: KEX algorithms: mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,ext-info-c,kex-strict-c-v00@openssh.com
(snip)
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,ext-info-s,kex-strict-s-v00@openssh.com
(snip)
debug3: kex_choose_conf: will use strict KEX ordering
debug1: kex: algorithm: mlkem768x25519-sha256
(snip)
Wireshark による KEX パケット解析
Wireshark の最新版では、SSH の PQ/T Hybrid KEX が正しくデコードされます。
SSH_MSG_KEX_HYBRID_INIT
従来方式の公開鍵と PQC 対応の公開鍵を連結した mlkem768x25519-sha256 の C_INIT が確認できます。
SSH_MSG_KEX_HYBRID_REPLY
従来方式の公開鍵と PQC 対応の公開鍵を連結した mlkem768x25519-sha256 の S_REPLY が確認できます。
サーバ側で PQC 対応 KEX を無効化した場合の挙動
SSH サーバの設定を変更します。
echo 'KexAlgorithms curve25519-sha256' | sudo tee -a /opt/openssh-10.2/etc/sshd_config > /dev/null
クライアント側で KEX 指定しないで接続した場合
/opt/openssh-10.2/bin/ssh localohast -p 10022 -vvv
debug ログ(警告メッセージ・KexAlgorithms 選択確認)
OpenSSH v10.1 以降では、curve25519-sha256 等 PQC 非対応 KEX が選ばれた場合に警告メッセージが表示されます。
(snip)
debug1: SSH2_MSG_KEXINIT sent
debug3: receive packet: type 20
debug1: SSH2_MSG_KEXINIT received
debug2: local client KEXINIT proposal
debug2: KEX algorithms: mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,ext-info-c,kex-strict-c-v00@openssh.com
(snip)
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,ecdh-sha2-nistp256,ext-info-s,kex-strict-s-v00@openssh.com
(snip)
debug3: kex_choose_conf: will use strict KEX ordering
debug1: kex: algorithm: curve25519-sha256
(snip)
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
クライアント側で非 PQC KEX を明示指定して接続した場合
/opt/openssh-10.2/bin/ssh localhost -p 10022 -vvv -o KexAlgorithms=curve25519-sha256
debug ログ(警告メッセージ・KexAlgorithms 選択確認)
この場合は、クライアント側が意図的に PQC 非対応 KEX を選択したとみなされるため、警告メッセージは表示されません。
(snip)
debug1: SSH2_MSG_KEXINIT sent
debug3: receive packet: type 20
debug1: SSH2_MSG_KEXINIT received
debug2: local client KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,ext-info-c,kex-strict-c-v00@openssh.com
(snip)
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,ecdh-sha2-nistp256,ext-info-s,kex-strict-s-v00@openssh.com
(snip)
debug3: kex_choose_conf: will use strict KEX ordering
debug1: kex: algorithm: curve25519-sha256
(snip)
まとめ
本記事では、OpenSSH v10.2p1 を用いて mlkem768x25519-sha256 がデフォルトで選択されることを確認しました。
また、Wireshark によるハイブリッド鍵交換メッセージの解析や PQC 非対応 KEX を使用した場合の警告メッセージについても確認しました。
PQC への移行は今後ますます重要となりますので、ぜひご自身の環境でも検証してみてください。
参考文献
draft-ietf-sshm-mlkem-hybrid-kex
OpenSSH: Post-Quantum Cryptography

