opensslコマンドを使って暗号化したり、復号化したり、オプションの意味がわからなくてOpenSSL本体のソースを読んだりした

opensslコマンドというと、SSL証明書の更新作業の際にこんな感じで一連のコマンドを実行していた記憶があります。

```
鍵付きの秘密鍵を作成
$ openssl genrsa -des3 -out 鍵付き秘密鍵のファイル名 2048
鍵付きの秘密鍵から鍵なしの秘密鍵を作成
$ openssl rsa -in 鍵付き秘密鍵のファイル名 -out 鍵なし秘密鍵のファイル名
CSRファイルを作る前に現状のCSRファイルの中身を確認
$ openssl req -in CSRのファイル名 -text
鍵なしの秘密鍵からCSRファイルを作成
$ openssl req -nodes -new -key 鍵なし秘密鍵のファイル名 -out CSRのファイル名
ローカルでSSL証明書の有効期限を確認
$ openssl x509 -noout -dates -in SSL証明書のファイル名
HTTPS経由でSSL証明書の有効期限を確認
$ HOST=qiita.com && echo |openssl s_client -connect $HOST:443 -servername $HOST 2>/dev/null |openssl x509 -noout -dates
```

つい最近、PHPで文字列の暗号化と復号化を実装した際に、「[openssl_encrypt](https://www.php.net/manual/ja/function.openssl-encrypt.php)」と「[openssl_decrypt](https://www.php.net/manual/ja/function.openssl-decrypt.php)」という関数を使ったんですが、「[openssl_](https://www.php.net/manual/ja/ref.openssl.php)」と関数名についているくらいですから、opensslコマンドでも同様のことができるんだろうなと思い、SSL証明書の更新作業のときにしか使ったことがなかったopensslコマンドのことが気になりはじめてしまい、opensslコマンドを利用した暗号化・復号化のやり方を調べてみました。

# 今回の実行環境
- macOS Catalina 10.15.7
- Docker 20.10.6
- CentOS Linux 8.3.2011
- OpenSSL 1.1.1g

# 事前準備

今回はDockerを利用し、[CeontOS](https://hub.docker.com/_/centos)8の環境下で作業を行うので、コンテナを起動してコンテナの中に入っておきます。

```
$ docker container run -it --rm centos:8
```

コンテナに入った状態で、opensslコマンドをインストールします。
作業中にマニュアルを利用するのでman-dbも同時にインストールしておきます。

```
# dnf install openssl man-db -y
```

インストールが完了したらバージョンを確認しておきましょう。（2021年7月3日時点の）「centos:8」の環境ではデフォルトで「1.1.1g」というバージョンがインストールされるようです。
（[Vagrant](https://www.vagrantup.com/)で[CentOS8](https://app.vagrantup.com/centos/boxes/8)の環境を構築すると「OpenSSL 1.1.1」（末尾に「g」がつかないバージョン）がインストールされるので、操作している環境によって同じCentOS8でもデフォルトのバージョンが異なる可能性があります）

```
# openssl version
OpenSSL 1.1.1g FIPS  21 Apr 2020
```

# opensslコマンドとは

さっそくファイルの暗号化といきたいんですが、その前にopensslコマンドの概要について触れておきましょう。
サブコマンドで `help` を指定すると以下の3つの分類にわかれて利用できるコマンドが表示されます。

1. Standard commands
    - SSL証明書の発行時に利用していた `genrsa` 、 `x509` などは「Standard commands」に分類されます。
1. Message Digest commands
    - 「Message Digest commands」は今回利用しませんが、入力に対するハッシュ値を出力する `md5` や `sha256` といったサブコマンドがあります。
1. Cipher commands
    - 今回利用する暗号化・復号化に関連するサブコマンドは「Cipher commands」に含まれています。

```
# openssl help
Standard commands
asn1parse         ca                ciphers           cms               
・・・省略・・・
ts                verify            version           x509              

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md2               
・・・省略・・・
sm3               

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
・・・省略・・・
zlib              
```

各分類毎に利用できるコマンドを表示するには `list` というサブコマンドが準備されています。

```
# openssl list -help
Usage: list [options]
Valid options are:
 -help                   Display this summary
 -1                      List in one column
 -commands               List of standard commands
 -digest-commands        List of message digest commands
 -digest-algorithms      List of message digest algorithms
 -cipher-commands        List of cipher commands
 -cipher-algorithms      List of cipher algorithms
 -public-key-algorithms  List of public key algorithms
 -public-key-methods     List of public key methods
 -disabled               List of disabled features
 -missing-help           List missing detailed help strings
 -options val            List options for specified command
```

例えば `openssl list -commands` を実行すると「Standard commands」で利用できるコマンドが一覧表示されます。
先ほども紹介しましたが、SSL証明書の発行作業で利用していた `genrsa` 、 `rsa` 、 `req` 、 `x509` 、 `s_client ` といったコマンドが表示されています。

```
# openssl list -commands
asn1parse         ca                ciphers           cms               
crl               crl2pkcs7         dgst              dhparam           
dsa               dsaparam          ec                ecparam           
enc               engine            errstr            gendsa            
genpkey           genrsa            help              list              
nseq              ocsp              passwd            pkcs12            
pkcs7             pkcs8             pkey              pkeyparam         
pkeyutl           prime             rand              rehash            
req               rsa               rsautl            s_client          
s_server          s_time            sess_id           smime             
speed             spkac             srp               storeutl          
ts                verify            version           x509 
```


# 秘密が書かれたファイルを暗号化

前置きが長くなりましたが、暗号化を行いたい秘密が書かれたファイルを用意します。

```
# echo '犯人はヤス' > secret.txt
```

念のため秘密の内容を確認しておきましょう。

```
# cat secret.txt 
犯人はヤス
```

***

opensslコマンドで暗号化を行う場合のサブコマンドは2種類の方法があります。
ここでは秘密が書かれたファイルの暗号化(Encrypt)を行いたいので、引数に `-e` を指定します。

１. サブコマンド　`enc` の引数に暗号アルゴリズムを渡す方法。（暗号アルゴリズムの前にハイフンが付いた形式）

```
# openssl enc -aes256 -e -in secret.txt -out encrypted.txt 
```

２. 暗号アルゴリズムをサブコマンドとして指定する方法。（暗号アルゴリズムの前にハイフンが付かない形式）

```
# openssl aes-256-cbc -e -in secret.txt -out encrypted.txt
```

***

サブコマンド `enc` で指定可能な暗号アルゴリズムの一覧を確認するには引数として `-list` または `-ciphers` を渡します。 `-ciphers` は `-list` のエイリアスとして機能します。

```
# openssl enc -list
Supported ciphers:
-aes-128-cbc               -aes-128-cfb               -aes-128-cfb1             
-aes-128-cfb8              -aes-128-ctr               -aes-128-ecb 
・・・省略・・・
-rc5-ofb                   -seed                      -seed-cbc                 
-seed-cfb                  -seed-ecb                  -seed-ofb
```

または

```
# openssl enc -ciphers
```

***

暗号アルゴリズムをサブコマンドとして渡す場合に指定可能な一覧を確認する方法は `openssl list -help` で既に登場していましたが、サブコマンド `list` に引数として `-cipher-commands` を渡すことで表示されます。

```
# openssl list -cipher-commands
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb       
・・・省略・・・
seed-cbc          seed-cfb          seed-ecb          seed-ofb          
zlib              

```

***


色々と説明しましたが、秘密のファイル「secret.txt」を暗号化して「encrypted.txt」を作成してみましょう。
コマンド実行時に `enter 暗号アルゴリズム encryption password` というメッセージが表示されパスワード入力が求められますので、実際に利用する場合には秘密が守れそうなパスワードを入力しましょう。
※引数に `-pass` を渡すことでパスワードの指定方法が選択できますが、今回 `-pass` は未指定にしてコマンド実行時にパスワード入力が求められる形式で進めることとします。

```
# openssl enc -aes256 -e -in secret.txt -out encrypted.txt
enter aes-256-cbc encryption password:XXXXXXXXXXXX
Verifying - enter aes-256-cbc encryption password:XXXXXXXXXXXX
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
```

実行後に `WARNING` といった気になるメッセージが表示されていますが、ひとまず無視して暗号化後の「encrypted.txt」の中身を見てみます。
catしてみるとなにやら不穏な表示ですが、これは出力後のファイルがバイナリ形式となっているためです。ファイルへの出力自体は正しく行われているので暗号化には成功しているようです。

```
# cat encrypted.txt 
Salted__?!3*kLuݪn̖?D1ٵ`??[?)9v|??V\Ɩ?	??/
```

「encrypted.txt」が本当にバイナリ形式なのか不安な場合はfileコマンドで確認しましょう。
fileコマンドはDocker環境のCentOS8にはインストールされていないので、別途インストールが必要です。

```
# dnf install file -y
```

引数なしで実行すると親切な表示ですね。

```
# file encrypted.txt 
encrypted.txt: openssl enc'd data with salted password
```

`-i` を指定すると「charset」で文字コードが確認できます。バイナリ形式の場合は「binary」と表示されますので、想定通りバイナリ形式となっているようです。

```
# file -i encrypted.txt 
encrypted.txt: application/octet-stream; charset=binary
```

# 暗号化時の気になるメッセージについて

秘密のファイルの暗号化には成功しましたが、暗号化のコマンドを実行した際に以下のような気になるメッセージが表示されていました。

```
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
```

`deprecated key derivation used.` とのことですが、 `-iter` または `-pbkdf2` を引数として指定することを推奨しているようです。
ヘルプを見てみると、 `-iter` は `PBKDF2` を利用する際に指定するオプションのようで数値を渡す必要がありそうです。だとすると `-iter` を指定する場合は `-pbkdf2` も指定する必要がありそうで、  `-iter or -pbkdf2` という表現はなんだかおかしいような気がします。
`-pbkdf2` は直訳だと「パスワードベースの鍵導出関数のバージョン2を使用する」だそうです。全然わかりませんね。

```
# openssl enc -help
・・・省略・・・
 -iter +int          Specify the iteration count and force use of PBKDF2
 -pbkdf2             Use password-based key derivation function 2
```

ヘルプだと情報が少ないので `man openssl` でマニュアルを見てみましょう。

```
# man openssl
```

マニュアル内の `SEE ALSO` の箇所に `enc(1)` という記載があります。サブコマンド `enc` については別途マニュアルが準備されているようです。

```
・・・省略・・・
NAME
       openssl - OpenSSL command line tool
・・・省略・・・
SEE ALSO
       asn1parse(1), ca(1), ciphers(1), cms(1), config(5), crl(1), crl2pkcs7(1), dgst(1), dhparam(1), dsa(1), dsaparam(1), ec(1), ecparam(1),
       enc(1), engine(1), errstr(1), gendsa(1), genpkey(1), genrsa(1), nseq(1), ocsp(1), pkcs12(1), pkcs7(1), pkcs8(1), pkey(1), pkeyparam(1),
       pkeyutl(1), prime(1), rehash(1), req(1), rsa(1), rsautl(1), s_client(1), s_server(1), s_time(1), sess_id(1), smime(1), speed(1), spkac(1),
       srp(1), storeutl(1), sslpasswd(1), sslrand(1), ts(1), verify(1), version(1), x509(1), crypto(7), ssl(7), x509v3_config(5)
```

なので `enc(1)` のマニュアルを見てみましょう。

```
# man enc
または
# man 1 enc
または
# man openssl enc
または
# man 1 openssl enc
```

`-iter` と `-pbkdf2` に関する記述がありました。
`-iter` の回数に応じて暗号化を繰り返し行うという感じでしょうか。この回数が多いほどブルートフォース攻撃への耐性が高くなる（突破するための時間が長くかかる）といった説明のようです。
`-pbkdf2` は `-iter` で暗号化の回数が指定されていなければ、デフォルトの回数で暗号化を行うとのこと。いや、そのデフォルトの回数って何回。。。

```
・・・省略・・・
NAME
       openssl-enc, enc - symmetric cipher routines
・・・省略・・・
       -iter count
           Use a given number of iterations on the password in deriving the encryption key.  High values increase the time required to brute-force
           the resulting file.  This option enables the use of PBKDF2 algorithm to derive the key.

       -pbkdf2
           Use PBKDF2 algorithm with default iteration count unless otherwise specified.
```

以上のことを踏まえ、疑問は2つです。

- `-iter` は `PBKDF2` という鍵導出関数を利用する際に必要なオプションのはずなのに `-iter` または `-pbkdf2` のどちらかを引数として指定すればOKみたいな記述になっている。
- `-pbkdf2` は `-iter` が指定されていない場合はデフォルトの回数で暗号化を行うとのことだが、そのデフォルト回数が不明。

# OpenSSLのソースファイルを読んでみる

ということで、マニュアルに載ってなければソースを読むしかないですね。
[前回はOpenSSHのソースを読んでみました](https://qiita.com/akase244/items/d640cb2235bc0995bd87)が今回はOpenSSLです。まぁ、臆さずにいってみましょう。

「centos:8」の環境では「1.1.1g」というバージョンがインストールされることがわかっているので、[OpenSSLのGitHubリポジトリ](https://github.com/openssl/openssl)で[「1.1.1g」のタグのページ](https://github.com/openssl/openssl/releases/tag/OpenSSL_1_1_1g)を開きます。

ソースファイルのダウンロードを行います。

```
$ curl -LO https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_1_1_1g.tar.gz
```

ダウンロードが完了したら展開しておきます。

```
$ tar zxvf OpenSSL_1_1_1g.tar.gz
$ cd openssl-OpenSSL_1_1_1g
```

これでソースファイルを読む準備が整いました。

## 2つの疑問を探る

手がかりは `-iter` と `-pbkdf2` の2つのキーワードのみなので、ひとまず何も考えずに `-iter` をgrepしてみたところ、例の `Using -iter or -pbkdf2 would be better.` というメッセージが `apps/enc.c` でヒットしました。他はマニュアルページのファイルっぽいので、これは答えに近そうですね。

```
% grep -n '\-iter' * -r
apps/enc.c:484:                                    "Using -iter or -pbkdf2 would be better.\n");
doc/man1/enc.pod:31:[B<-iter count>]
doc/man1/enc.pod:119:=item B<-iter count>
doc/man1/pkcs8.pod:19:[B<-iter count>]
doc/man1/pkcs8.pod:92:=item B<-iter count>
doc/man1/pkcs8.pod:281: openssl pkcs8 -in key.pem -topk8 -v2 aes-256-cbc -iter 1000000 -out pk8.pem
doc/man1/pkcs8.pod:308:The B<-iter> option was added in OpenSSL 1.1.0.
```

該当箇所である `apps/enc.c` の[484行目の前後](https://github.com/openssl/openssl/blob/OpenSSL_1_1_1g/apps/enc.c#L463-L491)を見ると大きなヒントがありました。 `Using -iter or -pbkdf2 would be better.` というメッセージは変数 `pbkdf2` が `1` 以外の場合、つまり引数に `-pbkdf2` が指定されていない場合に出力されるようです。

```:apps/enc.c#L463-L491
463             if (pbkdf2 == 1) {
・
・
481             } else {
482                 BIO_printf(bio_err, "*** WARNING : "
483                                     "deprecated key derivation used.\n"
484                                     "Using -iter or -pbkdf2 would be better.\n");
・
・
491             }
```

まず、変数 `pbkdf2` の定義元を探ってみます。ファイルの先頭から `pbkdf2` を検索してみると 　`enc_main` 関数の中の[113行目](https://github.com/openssl/openssl/blob/OpenSSL_1_1_1g/apps/enc.c#L113)で定義されていました。変数 `pbkdf2` の初期値は `0` のようです。そして、114行目には `iter` という変数も見つかりました。

```:apps/enc.c#L92-L114
 92 int enc_main(int argc, char **argv)
 93 {
 94     static char buf[128];
 95     static const char magic[] = "Salted__";
 96     ENGINE *e = NULL;
・
・
112     unsigned char *buff = NULL, salt[PKCS5_SALT_LEN];
113     int pbkdf2 = 0;
114     int iter = 0;
```

変数に値をセットする場合にこのソース内ではどのような書式が標準の形式かわかりませんでしたが、変数が定義されている箇所の周辺を見ると、どうやらこのソースの中では「変数名[空白]=[空白]値」が基本ルールなのではないかと予想されます。ということで `pbkdf2 = 1` が行われている箇所をgrepしてみます。すると2箇所該当行が見つかりました。266行目と269行目ということで該当している箇所も近いので2箇所同時に見てみましょう。

```
$ grep -n 'pbkdf2 = 1' apps/enc.c 
266:            pbkdf2 = 1;
269:            pbkdf2 = 1;
```

138行目以降ではループしながら渡ってきた各引数に応じて処理を行っているようですが、[263〜272行目](https://github.com/openssl/openssl/blob/OpenSSL_1_1_1g/apps/enc.c#L263-L272)に答えが書かれていました。

まず263行目の `case OPT_ITER:` です。引数に `-iter` と数値が指定されていたら266行目で変数 `pbkdf2` に `1` をセットしています。

次に268行目の `case OPT_PBKDF2:` です。 `-pbkdf2` が引数に指定されていたら269行目で変数  `pbkdf2` に `1` をセットして、かつ、270行目で変数 `iter` が `0` （初期値の状態）つまり引数 `-iter` が未指定だったら、次の271行目で変数 `iter` に `10000` をセットしています。

```:apps/enc.c#L138-L281
138     prog = opt_init(argc, argv, enc_options);
139     while ((o = opt_next()) != OPT_EOF) {
140         switch (o) {
141         case OPT_EOF:
142         case OPT_ERR:
・
・
263         case OPT_ITER:
264             if (!opt_int(opt_arg(), &iter))
265                 goto opthelp;
266             pbkdf2 = 1;
267             break;
268         case OPT_PBKDF2:
269             pbkdf2 = 1;
270             if (iter == 0)    /* do not overwrite a chosen value */
271                 iter = 10000;
272             break;
・
・
281     }
```

はい、ということで疑問だった `Using -iter or -pbkdf2 would be better.` と `Use PBKDF2 algorithm with default iteration count` の2つ謎が解けました。

`-iter` と `-pbkdf2` のどちらかが引数にセットされていたら、いずれの引数も有効となるように補完しあう仕組みとなっており、 `with default iteration count` は `10000` だということがわかりました。

ちなみに `-iter` は `10000` 未満の数字、例えば `-iter 1` のように極端に小さな数字を引数に指定した場合でも特に警告が出たりすることはありません。
コード上は変数 `pbkdf2` がセットされていれば警告は出力されないので、そりゃそうだという感じではありますが、デフォルト値の `10000` より小さくてもいいんだ、というモヤモヤ感は残りました。

それともう一点、enc_main関数の序盤で `const` の定義をしている箇所があるのに、 `iter = 10000;` のようにマジックナンバーで値をセットしているところが気になりました。
C言語の定数の書き方はよくわかってないですが、int型に対しても `const int 変数名` のような定義はできそうな雰囲気なので、今後デフォルト値が変わる可能性があるかどうかはわかりませんが、 `const int default_iter_count = 10000` みたいな定義しておいて、 `case OPT_PBKDF2:` で `iter = default_iter_count;` と書く方がよいかもなぁとか思いました。

# 改めて秘密が書かれたファイルを暗号化

めちゃくちゃ遠回りしましたが、改めて `deprecated key derivation used.` の警告が出ない形式でファイルを暗号化してみたいと思います。
`-pbkdf2` を利用する形式にして `-iter` に `99999` を指定してみます。
すると、今回は警告が消えた状態でファイルの暗号化が完了しました。

```
# openssl enc -aes256 -e -pbkdf2 -iter 99999 -in secret.txt -out encrypted.txt
enter aes-256-cbc encryption password:XXXXXXXXXXXX
Verifying - enter aes-256-cbc encryption password:XXXXXXXXXXXX
```

# 秘密が書かれたファイルを復号化

暗号化ができたので、今度は秘密が書かれたファイルを復号化してみましょう。
ファイルの復号化(Decrypt)を行う場合は引数に `-d` を指定します。復号化も暗号化の場合と同様に以下の2種類の方法で行えます。

１. サブコマンド　enc の引数に暗号アルゴリズムを渡す方法。（暗号アルゴリズムの前にハイフンが付いた形式）

```
# openssl enc -aes256 -d -in encrypted.txt -out decrypted.txt 
```

２. 暗号アルゴリズムをサブコマンドとして指定する方法。（暗号アルゴリズムの前にハイフンが付かない形式）

```
# openssl aes-256-cbc -d -in encrypted.txt -out decrypted.txt
```

復号化のやり方はわかったので実際にやってみましょう。注意点として、暗号化を行った際の `-pbkdf2 -iter 99999` の部分は同じ引数を与える必要があります。パスワード入力後に何も表示されなければ復号化に成功しています。

```
# openssl enc -aes256 -d -pbkdf2 -iter 99999 -in encrypted.txt -out decrypted.txt
enter aes-256-cbc decryption password:XXXXXXXXXXXX
```

パスワードや引数の値を間違えると、 `bad decrypt` というメッセージが表示され復号化に失敗したことがわかります。

```
# openssl enc -aes256 -d -pbkdf2 -iter 1000 -in encrypted.txt -out decrypted.txt
enter aes-256-cbc decryption password:XXXXXXXXXXXX
bad decrypt
140674163349312:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto/evp/evp_enc.c:616:
```

それではいよいよ復号化されたファイル「decrypted.txt」の内容を確認してみましょう。

```
# cat decrypted.txt 
犯人はヤス
```

とんでもない秘密を知ってしまいましたね。。。

# まとめ

[前回のOpenSSHの場合](https://qiita.com/akase244/items/d640cb2235bc0995bd87)はただただ読むだけだったので非常に疲れましたが、今回は暗号化を行いたいファイルを作って、暗号化して、復号化してみるといった一連の手順を実際にやってみながらだったので、こういうオプションを渡すとこういう風に動くんだなといったライブ感があってとても楽しみながらソースを読むことができました。

SSHやSSLと聞くと、セキュリティ、暗号、難しい、無理となりがちかもしれませんが、今回自分が知りたかった箇所については案外簡単に読むことができました。

この仕事をやっているとドキュメントに書かれていない動作・仕様にぶつかることはよくある話なので、ソースを読む訓練はしておいた方がよいかなぁと思った次第です。

# おまけ

今回は短い文字列が記載されたファイルの暗号化を行いました。ファイルサイズとしては3バイト。
コマンドを実行してから暗号化・復号化が完了するまでの時間は一瞬です。

```
# ls -l secret.txt 
-rw-r--r-- 1 root root 16 Jul  3 02:15 secret.txt
```

ファイルサイズや `-iter` の回数によっては暗号化・復号化にもっと時間がかかることが予想されます。
なので、小さなサイズのテキストファイルではなく以下のような約500KBのPDFファイルを準備して、実際にどれくらいの時間がかかるのか試してみました。

```
# ls -lh 500kb.pdf 
-rw-r--r-- 1 root root 501K Jul  3 02:14 500kb.pdf
```

# 処理条件
- PC: MacBook Pro
- CPU: Intel Core i7 2.3GHz クアッドコア
- メモリ: 32GB
- 暗号アルゴリズム: aes-256-cbc
- 暗号対象のファイルサイズ: 500キロバイト
- 暗号対象のファイル形式: PDFファイル

`-iter` が `10000` 回の場合

```
# time openssl enc -aes256 -e -pbkdf2 -iter 10000 -in 500kb.pdf -out encrypted.pdf
enter aes-256-cbc encryption password:XXXXXXXXXXXX
Verifying - enter aes-256-cbc encryption password:XXXXXXXXXXXX

real	0m1.094s
user	0m0.025s
sys 	0m0.007s
```

`-iter` が `100000` 回の場合

```
# time openssl enc -aes256 -e -pbkdf2 -iter 100000 -in 500kb.pdf -out encrypted.pdf
enter aes-256-cbc encryption password:XXXXXXXXXXXX
Verifying - enter aes-256-cbc encryption password:XXXXXXXXXXXX

real	0m1.370s
user	0m0.117s
sys 	0m0.007s
```

`-iter` が `1000000` 回の場合

```
# time openssl enc -aes256 -e -pbkdf2 -iter 1000000 -in 500kb.pdf -out encrypted.pdf
enter aes-256-cbc encryption password:XXXXXXXXXXXX
Verifying - enter aes-256-cbc encryption password:XXXXXXXXXXXX

real	0m2.100s
user	0m1.000s
sys 	0m0.007s
```

`-iter` が `10000000` 回の場合

```
# time openssl enc -aes256 -e -pbkdf2 -iter 10000000 -in 500kb.pdf -out encrypted.pdf
enter aes-256-cbc encryption password:XXXXXXXXXXXX
Verifying - enter aes-256-cbc encryption password:XXXXXXXXXXXX

real	0m11.103s
user	0m9.782s
sys 	0m0.019s
```

`-iter` が `100000000` 回の場合

```
# time openssl enc -aes256 -e -pbkdf2 -iter 100000000 -in 500kb.pdf -out encrypted.pdf
enter aes-256-cbc encryption password:XXXXXXXXXXXX
Verifying - enter aes-256-cbc encryption password:XXXXXXXXXXXX

real	1m39.757s
user	1m38.319s
sys 	0m0.015s
```

`-iter` が `1000000000` 回の場合

```
# time openssl enc -aes256 -e -pbkdf2 -iter 1000000000 -in 500kb.pdf -out encrypted.pdf
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:

real	16m38.381s
user	16m36.887s
sys 	0m0.037s
```

予想通り `-iter` の回数を増やすほど時間がかかることがわかりました。
いやしかし、1000000000回を指定するとPCが唸りを上げまくってうるさかったので処理結果が返ってくる頃には壊れちゃうんじゃないかと思いました。

# 参考URL
- [SSL証明書の内容をopensslで確認する](https://qiita.com/m-chika/items/e4936feb4087b7ddbe8b)
- [SSL証明書の有効期限や内容を確認する方法一覧](https://qiita.com/bezeklik/items/a8e6296d7e21a7a8a9fe)
- [[小ネタ]OpenSSLコマンドを使って色々確認する](https://qiita.com/toshihirock/items/eb1337ba471b4757071a)
- [opensslコマンドの使い方](https://qiita.com/hana_shin/items/6d9de0847a06d8ee95cc)
- [opensslコマンドで簡単なファイル暗号化](https://qiita.com/ikuwow/items/1cdb057352c06fd3d727)
- [OpenSSLでファイルの暗号化・復号化するための備忘録](https://qiita.com/Yarimizu14/items/49690c141b62507e00d9)
- [OpenSSLでファイルの暗号化と復号を行う](https://www.karakaram.com/file-encryption-using-openssl/)
- [openssl ver.1.1.1 で 「Using -iter or -pbkdf2 would be better.」や「bad decrypt」 error](https://end0tknr.hateblo.jp/entry/20191124/1574563899)
- [暗号化のAES方式とは？ほかの種類との違い・実施方法を解説！](https://it-trend.jp/encryption/article/64-0070)
- [さらばDES暗号、2023年終了へカウントダウン](https://xtech.nikkei.com/atcl/nxt/column/18/00001/00986/)