この記事の情報は執筆時点のものであり、将来の仕様変更などにより成り立たなくなる可能性がある。
OpenSSL のバージョンの確認
openssl version
コマンドで、OpenSSL のバージョンを確認できる。
OpenSSL のコマンドラインツールで Ed25519 の署名や検証を行うには、OpenSSL 3 系でないといけないようである。
たとえば
さくらのクラウドシェル | さくらインターネット
では、この条件を満たす OpenSSL が利用できる。
sakura@cloud-shell% openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
JSLinux の Alpine Linux 3.12.0 では、OpenSSL 1.1.1 系が使用できる。
このバージョンでは、Ed25519 の鍵生成はできるが、署名や検証はできないようである。
localhost:~# openssl version
OpenSSL 1.1.1g 21 Apr 2020
鍵生成
秘密鍵を生成する
openssl genpkey -algorithm ed25519 -out key.pem
コマンドで、Ed25519 の秘密鍵を生成し、ファイル key.pem
に書き込むことができる。
出力は、たとえば以下のようになる。
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIOYMyIKdWwR4RJO/RKp7J9c9O/6228gETgey9hohiQTq
-----END PRIVATE KEY-----
ここでは解説用に公開しているが、実際に用いる秘密鍵は公開してはいけない。
秘密鍵から公開鍵を生成する
openssl pkey -in key.pem -pubout -out key.pub
コマンドで、秘密鍵のファイル key.pem
を読み込み、対応する公開鍵をファイル key.pub
に書き込むことができる。
出力は、たとえば以下のようになる。
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA9sOdLDyYCOXe+fKmEb+6B2MY/qWFUJpG1AUvRNUtokY=
-----END PUBLIC KEY-----
鍵の中身を確認する
grep
コマンドの -v
オプションを用いて -----
を含まない行を取り出し、base64 -d
コマンドでデコードすることで、Base64 エンコードされたデータの中身を確認できる。
sakura@cloud-shell% grep -v -e ----- key.pem | base64 -d | od -Ax -t x1
000000 30 2e 02 01 00 30 05 06 03 2b 65 70 04 22 04 20
000010 e6 0c c8 82 9d 5b 04 78 44 93 bf 44 aa 7b 27 d7
000020 3d 3b fe b6 db c8 04 4e 07 b2 f6 1a 21 89 04 ea
000030
sakura@cloud-shell% grep -v -e ----- key.pub | base64 -d | od -Ax -t x1
000000 30 2a 30 05 06 03 2b 65 70 03 21 00 f6 c3 9d 2c
000010 3c 98 08 e5 de f9 f2 a6 11 bf ba 07 63 18 fe a5
000020 85 50 9a 46 d4 05 2f 44 d5 2d a2 46
00002c
秘密鍵 key.pem
および公開鍵 key.pub
のいずれも、ヘッダに続いて 32 バイトの鍵データが格納されている。
e60cc8829d5b04784493bf44aa7b27d73d3bfeb6dbc8044e07b2f61a218904ea
f6c39d2c3c9808e5def9f2a611bfba076318fea585509a46d4052f44d52da246
たとえば、Ed25519 Online Tool を用いて、この公開鍵がこの秘密鍵に対応するものであることを確認できる。
鍵を DER 形式で出力する
鍵の生成時に -outform DER
オプションを追加することで、DER 形式、すなわちデフォルトでは Base64 エンコードされて出力されていた部分の中身だけからなるバイナリ形式で出力できる。
sakura@cloud-shell% openssl genpkey -algorithm ed25519 -outform DER -out key2.bin
sakura@cloud-shell% od -Ax -t x1 key2.bin
000000 30 2e 02 01 00 30 05 06 03 2b 65 70 04 22 04 20
000010 7f d7 8d 83 e0 cf e6 80 c9 0a 8b 43 80 2d da 3d
000020 3c d5 72 b2 15 02 76 03 ce e8 f5 43 b1 dc 10 80
000030
既存の鍵を DER 形式に変換することもでき、Base64 エンコードのデコード結果と同じ結果が得られることが確認できる。
sakura@cloud-shell% openssl pkey -in key.pem -outform DER -out key.bin
sakura@cloud-shell% od -Ax -t x1 key.bin
000000 30 2e 02 01 00 30 05 06 03 2b 65 70 04 22 04 20
000010 e6 0c c8 82 9d 5b 04 78 44 93 bf 44 aa 7b 27 d7
000020 3d 3b fe b6 db c8 04 4e 07 b2 f6 1a 21 89 04 ea
000030
署名
署名対象のデータを用意する
今回は、文字列 hello
に対して署名を行った。
echo
コマンドの -n
オプションを用いて、改行の入っていないデータを用意した。
sakura@cloud-shell% echo -n hello > message.txt
sakura@cloud-shell% od -Ax -t x1 message.txt
000000 68 65 6c 6c 6f
000005
署名を行う
openssl pkeyutl -sign -inkey key.pem -rawin -in message.txt -out signature.bin
コマンドで、Ed25519 署名を行うことができる。
以下のオプションを用いた。
オプション | 意味 |
---|---|
-sign |
署名を行う |
-inkey key.pem |
署名に用いる鍵ファイルを指定する |
-rawin |
入力データは(ハッシュ値ではなく)署名対象のメッセージである |
-in message.txt |
入力データのファイルを指定する |
-out signature.bin |
署名データを保存するファイルを指定する |
Ed25519 署名では計算方法の関係でハッシュ値ではなくメッセージそのものが必要であるため、-rawin
オプションは必須である。
メッセージのハッシュ値を用いて署名を行う Ed25519ph には未対応のようである。
署名の内容を確認する
生成された署名データの内容を確認する。
sakura@cloud-shell% openssl pkeyutl -sign -inkey key.pem -rawin -in message.txt -out signature.bin
sakura@cloud-shell% od -Ax -t x1 signature.bin
000000 e8 d5 45 52 5c 86 c5 3f ee 74 f5 15 a4 b0 29 46
000010 4e ee d7 b5 e6 62 a6 7d 29 39 bf 89 a7 3f 65 4c
000020 e8 f2 be 00 ad 59 24 95 6b 4d 28 23 fd e2 dc 42
000030 99 49 bf 2b 7d cc 6d b0 dc 9d 83 e4 f8 17 c3 0c
000040
署名データは、署名のデータがそのままバイナリで格納されるようである。
同じ鍵を用いて Ed25519 Online Tool で生成した署名と一致することが確認できる。
署名の検証
openssl pkeyutl -verify -pubin -inkey key.pub -rawin -in message.txt -sigfile signature.bin
コマンドで、署名の検証を行うことができる。
以下のオプションを用いた。(署名時にも用いたオプションは省略)
オプション | 意味 |
---|---|
-verify |
署名の検証を行う |
-pubin |
指定する鍵は(秘密鍵ではなく)公開鍵である |
-sigfile signature.bin |
署名を読み込むファイルを指定する |
署名の検証に成功すると、Signature Verified Successfully
と出力され、終了コード 0
が返る。
sakura@cloud-shell% openssl pkeyutl -verify -pubin -inkey key.pub -rawin -in message.txt -sigfile signature.bin
Signature Verified Successfully
sakura@cloud-shell% echo $?
0
署名でないデータを署名として渡したり、違うメッセージを入力として渡したりすると、署名の検証に失敗する。
署名の検証に失敗すると、Signature Verification Failure
と出力され、終了コード 1
が返る。
sakura@cloud-shell% head -c 64 /dev/urandom > random.bin
sakura@cloud-shell% echo -n hellp > hellp.txt
sakura@cloud-shell% openssl pkeyutl -verify -pubin -inkey key.pub -rawin -in message.txt -sigfile random.bin
Signature Verification Failure
sakura@cloud-shell% echo $?
1
sakura@cloud-shell% openssl pkeyutl -verify -pubin -inkey key.pub -rawin -in hellp.txt -sigfile signature.bin
Signature Verification Failure
sakura@cloud-shell% echo $?
1
公開鍵のかわりに秘密鍵を指定しても、署名の検証を行うことができる。
逆に、公開鍵を指定して署名を行うことはできない。
sakura@cloud-shell% openssl pkeyutl -verify -inkey key.pem -rawin -in message.txt -sigfile signature.bin
Signature Verified Successfully
sakura@cloud-shell% openssl pkeyutl -sign -pubin -inkey key.pub -rawin -in message.txt -out signature_p.bin
A private key is needed for this operation
pkeyutl: Error initializing context
おまけ:Ed448 署名
秘密鍵の生成時、-algorithm ed25519
のかわりに -algorithm ed448
とすることで、Ed448 署名を扱うことができる。
他のコマンドでは、署名の種類をオプションで指定しない (署名の種類の情報は鍵データに埋め込まれている) ので、Ed25519 署名と同じコマンドを用いることができる。
sakura@cloud-shell% openssl genpkey -algorithm ed448 -out key448.pem
sakura@cloud-shell% cat key448.pem
-----BEGIN PRIVATE KEY-----
MEcCAQAwBQYDK2VxBDsEOWG0XRtJgiEPC9G9Uc3yOVUOh8ggaP6sljdJi/qKqKJi
UOiYU0D/mV3lfYN7rvo430RYHxotRBgA6g==
-----END PRIVATE KEY-----
sakura@cloud-shell% openssl pkey -in key448.pem -pubout -out key448.pub
sakura@cloud-shell% cat key448.pub
-----BEGIN PUBLIC KEY-----
MEMwBQYDK2VxAzoA5puanqaGESJQribqxYXMUFi/pljoqEVLnN4M06klofCXNEmF
mz+H9z16Dccsa6gh+isI5poZfzgA
-----END PUBLIC KEY-----
sakura@cloud-shell% openssl pkeyutl -sign -inkey key448.pem -rawin -in message.txt -out signature448.bin
sakura@cloud-shell% od -Ax -t x1 signature448.bin
000000 7d 0b 60 fb 2f d3 67 3b 6f dc b7 5c b8 05 54 e9
000010 94 59 80 d5 ef b1 83 0c 42 ab b0 e2 98 7b d5 18
000020 a2 a8 68 29 bb 80 c6 d6 e8 dc eb 70 8d 85 a7 3c
000030 32 9b e9 7b 8d 53 c8 3d 80 00 a6 eb e2 19 35 85
000040 77 89 a7 76 75 60 c7 a4 c8 02 d6 1c 18 80 d9 b8
000050 6e 4e 1e ac 36 45 23 82 5f 14 3d 2c e4 b0 f5 0a
000060 21 ca 0a ca db 41 0f 1d 58 41 ab 44 95 c9 6c 9e
000070 19 00
000072
sakura@cloud-shell% openssl pkeyutl -verify -pubin -inkey key448.pub -rawin -in message.txt -sigfile signature448.bin
Signature Verified Successfully
まとめ
OpenSSL を用いて、Ed25519 の鍵生成・署名・検証を行う方法を確認した。
また、その際に扱う鍵や署名のデータの中身も確認した。