1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

さっそくOpenSSL3.5.0のPQC機能を使ってみる(コマンド編)

Last updated at Posted at 2025-04-11

はじめに

みなさんいつもお世話になっているOpenSSLですが,2025年4月8日にバージョン3.5.0がリリースされました.
NISTのPQC標準化活動によって標準化が決まったML-KEM,ML-DSA,SLH-DSAの3つのアルゴリズムが3.5.0でサポートされました.
PQCの詳細についてはまた後日まとめる予定です.

この記事ではOpenSSLコマンドを使ってML-KEM,ML-DSAを試してみます.
SLH-DSAを試してみようと思ったのですが,コマンドが用意されていなかったので今回は見送りました.

セットアップ

今回使った環境はUbuntu24.04です.
まずはOpenSSLのプログラムを入手してビルドします.

sudo apt update
sudo apt install -y gcc make  # 必要なツールをインストール

wget https://www.openssl.org/source/openssl-3.5.0.tar.gz
tar -xzf openssl-3.5.0.tar.gz
cd openssl-3.5.0
./Configure
make
sudo make install

openssl version  # バージョンが出力されると成功

最後にバージョンが出力されずエラーが出てしまったら次を試してください.
自分はエラーが出てこれで解決しました.

LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/openssl version
LD_LIBRARY_PATH=/usr/local/lib64 /usr/local/bin/openssl version

# 一つ目で正常に出力された場合
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

# 二つ目で正常に出力された場合
export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH

# 最後に反映
export PATH=/usr/local/bin:$PATH
source ~/.bashrc

一度ログアウトしてしまうと設定が元に戻ってしまうので注意.

※ 元々インストールされているOpenSSLを完全に置き換えてしまうとバージョンに依存しているプログラムが動かなくなってしまう恐れがあるため,今回は一時的な処置をとっています

OpenSSL3.5.0のPQC機能を使ってみる

ML-KEM

ML-KEMは格子暗号をベースにした鍵共有アルゴリズムです.
コマンドライン上で鍵生成,カプセル化,デカプセル化の3つの機能を使ってみます.
まずは秘密鍵と公開鍵を生成します.

鍵生成

openssl genpkey -algorithm ml-kem-512 -out mlkem512.priv -outpubkey mlkem512.pub -outform PEM

mlkem512.privmlkem512.pub というファイルが生成されていれば成功です.
次に共有秘密をカプセル化します.

カプセル化

openssl pkeyutl -encap -pubin -inkey mlkem512.pub -keyform pem -secret shared-secret-enc.bin -out mlkem512-ct.bin

ここで何も出力されず, shared-secret-enc.binmlkem512-ct.bin というファイルが生成されていれば成功です.
shared-secret-enc.binは共有秘密,mlkem512-ct.binは暗号文です.
最後にカプセル化された暗号文から共有秘密を導出するため,デカプセル化を行います.

デカプセル化

openssl pkeyutl -decap -inkey mlkem512.priv -keyform pem -secret shared-secret-dec.bin -in mlkem512-ct.bin

ここで何も出力されず, shared-secret-dec.bin というファイルが生成されていれば成功です.
導出された共有秘密が正しく共有されているか確認してみます.
この共有秘密は同じ値である必要があるので diffコマンドを使って確認します.

diff shared-secret-enc.bin shared-secret-dec.bin

ここで何も出力されなければ成功です.
不安な人は xxdコマンドを使ってバイナリの値を確認してみてください.

xxd shared-secret-enc.bin
xxd shared-secret-dec.bin

shared-secret-enc.binshared-secret-dec.binの値が同じであれば成功です.
今回はML-KEM512を使用しましたが,ML-KEM768,ML-KEM1024も同様に使用できます.

ML-DSA

ML-DSAは格子暗号をベースにした署名アルゴリズムです.
鍵生成,署名生成,署名検証の3つの機能を使ってみます.
まずは秘密鍵(署名鍵)と公開鍵(検証鍵)を生成します.

鍵生成

openssl genpkey -algorithm ml-dsa-44 -out mldsa44.priv -outpubkey mldsa44.pub -outform PEM

ここで,mldsa44.privmldsa44.pub というファイルが生成されていれば成功です.
次に,署名を生成します.

署名生成

echo "test text" > test.txt  # テスト用のファイルを作成
openssl pkeyutl -sign -in test.txt -inkey mldsa44.priv -keyform pem -out test.sig

ここで何も出力されず, test.sig というファイルが生成されていれば成功です.
最後に署名 test.sig の検証を行います.

署名検証

openssl pkeyutl -verify -pubin -inkey mldsa44.pub -keyform pem -in test.txt -sigfile test.sig

ここで,Signature Verified Successfullyと出力されれば成功です.
今回はML-DSA44を使用しましたが,ML-DSA65,ML-DSA87も同様に使用できます.

TLSで使ってみる

ML-KEMとML-DSAを使ってTLSで通信してみます.
まずは,ML-DSAを使って サーバ証明書を生成します.
自己証明書だけでもいいのですが,今回はCA証明書も生成し,サーバ証明書を発行します.
CAはRSA署名を使っています.

# 前節で生成した鍵はサーバの鍵として使う
mv mldsa44.priv server-key.pem
mv mldsa44.pub server-pubkey.pem

# CAの鍵を生成(RSA)
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:3072 -out ca-key.pem -outform PEM
openssl req -new -x509 -key ca-key.pem -out ca-cert.pem -days 3650 -subj "/CN=CA" -sha256

# サーバ証明書の生成
openssl req -new -key server-key.pem -out server-csr.pem -subj "/CN=localhost" -sha256
openssl x509 -req -in server-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 3650 -sha256

ここで,server-key.pemがサーバの秘密鍵,server-cert.pemがサーバの証明書,ca-key.pemがCAの秘密鍵,ca-cert.pemがCAの証明書です.
それではTLS通信を行ってみます.
同時に tcpdump を使ってパケットを取得し,後でWiresharkで確認します.
ターミナルを3つ立ち上げてください.
1つ目のターミナルでは,サーバを4433番ポートで待ち受けるようにします.

# サーバ側
openssl s_server -accept 4433 -cert server-cert.pem -key server-key.pem -tls1_3 -keylogfile server-key.log

2つ目のターミナルでは,クライアントでTLS接続を行います.
TLSハンドシェイクが完了すると対話モードで入力を待ち受けてしまうので, printfコマンドを使ってHTTPリクエストをパイプを使って入力・送信します.

# クライアント側
printf "GET / HTTP/1.0\r\n\r\n" | \
openssl s_client -connect localhost:4433 -CAfile ca-cert.pem -keylogfile client-key.log

3つ目のターミナルでは, tcpdumpを使ってパケットを取得します.

# tcpdump
sudo tcpdump -i lo -w pqctls.pcap

実行する順番は tcpdumpサーバクライアント の順番で実行してください.
実行するといろいろな情報が出てきますが,サーバとクライアントの両方でエラー表示がなければうまくTLS通信ができています.
特に何も表示がないのは,HTMLファイルを設定していないからなので気にしないでください.

Wiresharkで確認

tcpdumpで取得したパケットは pqctls.pcap というファイルに保存されています.
それでは, tcpdumpで取得したパケットをWiresharkで確認してみます.

ML-KEMの確認
まずはClient Helloの Extension: supported_groups のサポートされているグループを確認します.
これは鍵交換を行うための暗号化スキームのグループを示しています.

Supported Group: Unknown (0x11ec)
Supported Group: x25519 (0x001d)
Supported Group: secp256r1 (0x0017)
Supported Group: x448 (0x001e)
Supported Group: secp384r1 (0x0018)
Supported Group: secp521r1 (0x0019)
Supported Group: ffdhe2048 (0x0100)
Supported Group: ffdhe3072 (0x0101)

x25519からffdhe3072までは従来通りの楕円曲線暗号です.
ここで,Unknown (0x11ec)というグループが出ていますが,Wiresharkが対応していないためこのような表示になっています.
このグループはML-KEMではなく,X25519とML-KEM512のハイブリッド暗号化スキームです.
PQCはまだ歴史が浅いため,今後どちらかが破られたとしても,もう片方が安全ならば通信が解読されないようにするためにハイブリッド方式を採用していると思われます.
次にServer Helloの Extension: key_share > Extension: Key Share extension > Key Share Entry のサポートされているグループを確認します.

Extension: Key Share Entry: Group: Unknown (4588), Key Exchange length: 1120
  Group: Unknown (4588)
  Key Exchange length: 1120
  Key Exchange [...]: 9ef6...

4588は0x11ecと等しいので,Client HelloのUnknown (0x11ec)と同じグループであることがわかります.

ML-DSAの確認
通信がうまく行っているのでサーバ証明書の発行が可能になっており,クライアント(OpenSSL3.5.0)でML-DSAを使った証明書の検証ができていることがわかります.
せっかくなので通信を復号してサーバ証明書が本当に検証できるのかを確かめてみます.

TLS1.3ではサーバ証明書は暗号化されているので,Wiresharkで復号する必要があります.
Wiresharkeのメニューから EditPreferencesProtocolsTLS を選択します.
Pre-Master Secret log filenameserver-key.log を指定します.
OKを押して, pqctls.pcap を開きます.
すると,TLSのセッションが復号されていることがわかります.
Certificateレコードを探し次の情報まで辿ってください.

`Transport Layer Security`
  -> `TLSv1.3 Recode Layer: Handshake Protocol: Certificate`
    -> `Handshake Protocol: Certificate`
      -> `Certificates`
        -> `Certificate`

ここで右クリックをして Export packet Bytes を選択,Raw dataで server-key.der というファイル名で保存します.
.bin が拡張子についてしまうことがあるので server-key.der に変更しておきます.
opensslコマンドを使って読みやすいように変換して,中身を見てみます.

# 変換
openssl x509 -inform der -in server-key.der -out server-key.pem

# 中身を確認
openssl x509 -in server-key.pem -text -noout

# 出力
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            69:75:66:f6:b4:14:53:47:1b:80:78:9f:1b:f5:eb:ba:d4:cf:60:2f
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=CA
        Validity
            Not Before: Apr 11 04:29:14 2025 GMT
            Not After : Apr  9 04:29:14 2035 GMT
        Subject: CN=localhost
        Subject Public Key Info:
            Public Key Algorithm: ML-DSA-44
                ML-DSA-44 Public-Key:
                pub:
                    61:d0:4e:bf:dc:7e:56:90:2f:a2:30:e3:5c:97:7b:
                    04:e7:19:27:23:dc:94:9c:fe:1b:02:01:60:75:21:
                    ...(省略)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                8F:BF:B0:3A:FB:C9:F8:B3:C6:58:E5:4A:C2:EA:93:1D:BB:CD:C4:C6
            X509v3 Authority Key Identifier: 
                EE:8B:25:7C:58:08:6B:E0:43:0A:A1:78:C0:23:5D:DE:A3:F5:78:4F
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        11:bf:15:84:41:d0:8b:5f:b5:2c:4c:38:b3:cc:d8:e9:3e:aa:
        ca:d6:74:04:2c:65:6a:09:3c:9d:5c:73:2d:01:10:98:ba:b3:
        ...(省略)

Public Key Algorithm がML-DSA-44となっておりML-DSAを使ったX509証明書であることがわかります.
また, Signature Algorithm がsha256WithRSAEncryptionとなっており,CAの署名アルゴリズムがRSAであることがわかります.
このため,現在のCAがRSAやECDSAである場合でも,ML-DSAを使った証明書を発行することができます.

おわりに

OpenSSL3.5.0のPQC機能を使ってみました.
コマンドライン上で手軽に使えるようになり,これから普及していくと予想されます.
2030年を目標に動いているのでこれからの動向にも注目です.
SLH-DSAはまだコマンドが用意されていないので,実装され次第試してみたいと思います.
また,NISTのPQC標準化活動のround4ではHQCが標準化に選ばれ,2年後に正式な文書を発行する予定らしいです.
liboqsを使ってHQCを試してみるのも面白いかもしれません.
次回はopensslのAPIを使って,C言語でPQCを使ってみる予定です.

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?