🔐

OpenSSL コマンドを使った ChaCha20 での暗号化/復号

2024/11/10に公開

この記事は、 ChaCha20 の仕組みを学ぶために OpenSSL コマンドで実際に暗号化/復号を行ったときの記録です。誤りがあればコメントでご指摘ください。

ChaCha20 とは

TLS 1.2 の共通鍵暗号アルゴリズム

OpenSSL コマンドを使って暗号化・復号

0. OpenSSL の確認

OpenSSL がインストールしてあることを確認

$ /usr/local/bin/openssl version
OpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)

ChaCha20 が実装されていることを確認

$ /usr/local/bin/openssl ciphers -v TLSv1.2 | grep 'CHACHA20'
TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2 Kx=ECDH     Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
DHE-RSA-CHACHA20-POLY1305      TLSv1.2 Kx=DH       Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
RSA-PSK-CHACHA20-POLY1305      TLSv1.2 Kx=RSAPSK   Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
DHE-PSK-CHACHA20-POLY1305      TLSv1.2 Kx=DHEPSK   Au=PSK   Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-PSK-CHACHA20-POLY1305    TLSv1.2 Kx=ECDHEPSK Au=PSK   Enc=CHACHA20/POLY1305(256) Mac=AEAD
PSK-CHACHA20-POLY1305          TLSv1.2 Kx=PSK      Au=PSK   Enc=CHACHA20/POLY1305(256) Mac=AEAD

余談ですが、OpenSSL 1.0.2k-fips には ChaCha20 が実装されていなかったようです。これを機に OpenSSL 3.0.11 をインストールしました。

$ openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017
$ openssl ciphers -v TLSv1.2 | grep 'CHACHA20'
$

1. 鍵の生成

32バイトの16進数の乱数を生成。

$ /usr/local/bin/openssl rand -hex 32
c3eb6144e8010b786b11929c48c2f1cbb86025f41f4a3bddd32895b8152a8563

コマンド詳細

rand: 乱数生成
-hex: 16進数で指定バイト数分出力

2. 初期化ベクタの生成

16バイトの16進数の乱数を生成。

$ /usr/local/bin/openssl rand -hex 16
f0cfdee7013d11e31e6a79a48472d5fd

3. 対象ファイルを作成

実験に使うテキストファイルを作成。

$ vim example.txt
test

3. ChaCha20 で暗号化

暗号スイートを ChaCha20 に指定して対象ファイル(ここでは example.txt )を暗号化。

$ /usr/local/bin/openssl chacha20 -e -K c3eb6144e8010b786b11929c48c2f1cbb86025f41f4a3bddd32895b8152a8563 -iv f0cfdee7013d11e31e6a79a48472d5fd -in example.txt -out chacha20.bin

コマンド詳細

-e: 暗号化
-K: 鍵の直接指定
-iv: 初期化ベクタの直接指定
-in: 暗号化するファイルの指定
-out: 暗号化した出力ファイルの指定

4. 出力結果確認

暗号化されたファイルはバイナリファイルになっているので、 od コマンドで表示。

$ od -h chacha20.bin
0000000 3b9f f4f2 0099
0000005

5. 復号

暗号化のときと同様に鍵と初期化ベクタを指定して、復号。

$ /usr/local/bin/openssl chacha20 -d -K c3eb6144e8010b786b11929c48c2f1cbb86025f41f4a3bddd32895b8152a8563 -iv f0cfdee7013d11e31e6a79a48472d5fd -in chacha20.bin
test

コマンド詳細

-d: 復号

その他の実験結果

様々な長さの文字列を暗号化

暗号化されるバイナリのサイズは、元の文字列の長さに比例する。

// t
$ od -h chacha20.bin
0000000 549f
0000002
// test
$ od -h chacha20.bin
0000000 3b9f f4f2 0099
0000005
// Hello World.
// hogehoge
// piyopiyo
$ od -h chacha20.bin
0000000 3ba3 eced 7efc 8c35 20bc e09d ccfa c3ac
0000020 218a 4dc6 54b8 24fe ab3b 8b6d 29f6 00d5
0000037

不正な値で復号

鍵が正しくない

元の文字列にならない。

$ /usr/local/bin/openssl chacha20 -d -K c3eb6144e8010b786b11929c48c2f1cbb86025f41f4a3bddd32895b8152a8560 -iv f0cfdee7013d11e31e6a79a48472d5fd -in chacha20.bin
M▒▒.-

初期化ベクタが正しくない

元の文字列にならない。

$ /usr/local/bin/openssl chacha20 -d -K c3eb6144e8010b786b11929c48c2f1cbb86025f41f4a3bddd32895b8152a8563 -iv f0cfdee7013d11e31e6a79a48472d5f0 -in chacha20.bin
c▒▒

初期化ベクタが16進数でない

エラーが発生する。

$ /usr/local/bin/openssl chacha20 -d -K c3eb6144e8010b786b11929c48c2f1cbb86025f41f4a3bddd32895b8152a8563 -iv f0cfdee7013d11e31e6a79a48472d5fs -in chacha20.bin
non-hex digit
invalid hex iv value

備考

  • 上記は簡易的な暗号化であり、カウンタ等の入力値は省略してある。
  • 実際の SSL/TLS では固定値は使わず、ハンドシェイクの鍵交換時に各値を生成・共有してから使用している。

参考

SSL/TLS 実践入門
TLS暗号設定ガイドライン
とほほのOpenSSL入門
CentOS 7でOpenSSL LTS 3.0.xを使う

Discussion