【OpenSSL】 使い方を簡単に解説

## OpenSSL を解説していきます。

つ `openssl`

ドキュメント。 機能がいっぱいあっておもしろいです。

https://docs.openssl.org/master/man1/openssl/

とりあえず 乱数生成、暗号化、鍵作成、証明局、署名 等を説明していきます。

---

### 乱数生成

https://docs.openssl.org/master/man1/openssl-rand/

This command generates num random bytes using a cryptographically secure pseudo random number generator (CSPRNG)

CSPRNG についてはこちら https://ja.wikipedia.org/wiki/暗号論的擬似乱数生成器

乱数生成に関しては linux なら真性乱数の `/dev/random` を使うのが本筋かもしれません。でも、最近は試してないですが、昔はよくエントロピーが足りないせいでブロックされて動かなくなってたので、 `/dev/urandom` で十分だと思っています。

で、ではなんで `/dev/urandom` でなく openssl の `rand` を使うか、というと、 https://security.stackexchange.com/questions/47598/why-openssl-cant-use-dev-random-directly の非常に良くまとまってる2個目の回答のように、

- 速い
- Linux以外の環境でも動く

ということですかねー

というわけで使用例

```
$ openssl rand -hex 30
7154c50cc53df0b89337b3a7430e1a438d822ed9daecce7de435a349d2a1
```

---

### 暗号化

次は暗号化ですね 

https://docs.openssl.org/master/man1/openssl-enc/

暗号化コマンドの書き方は二種類あって、

- `openssl enc -aes-256-cbc -e < t1.txt`
- `openssl aes-256-cbc -e < t1.txt`

のどちらも許容されます。

上記 `aes-256-cbc` が cipher です。ご利用のバージョンの openssl でどの cipher が使えるかは、 `openssl list-cipher-commands` コマンドで確認できます。

どちらにしても `-e` が暗号化、 `-d` が復号です。

処理対象ファイルやアウトプットはパイプでも良いですし、 `-in` / `-out` で指定してもokです。

実際の使用例:

```
pv big.file | pigz | openssl aes-256-cbc -e -out big.file.gz.aes256
```

---

### 鍵作成

えーと次は鍵作成ですね。rsa/楕円曲線暗号で2種類やってみましょう。

https://docs.openssl.org/master/man1/openssl-genpkey/ こちらでもできますが、逆にパラメータが多くて面倒なので、 `genrsa` / `ecparam` を使って作ります。

まずは `genrsa`

https://docs.openssl.org/master/man1/openssl-genrsa/

```
openssl genrsa 4096 > /path/to/the.key
```

4096 が鍵長(bit)。 このぐらいがいいかと思います。

次は楕円曲線暗号

https://docs.openssl.org/master/man1/openssl-ecparam/

```
openssl ecparam -genkey -name secp384r1 > /path/to/the.key
```

---

### 証明局

秘密鍵を作ったら、次はサーバ証明書リクエストの作成ですかね？それとも署名用CAを作成しますか？

上記どちらにしろ、 まずはリクエストの生成なので、 `openssl req` を使います。

https://docs.openssl.org/master/man1/openssl-req/

CAの方を先にやってみますね。CentOS7でやる前提です。

上記 `/path/to/the.key` を `/etc/pki/CA/private/xxx001-ca01.key` にコピーするなりキー作成でいきなり作るなりしておきます。

```
openssl req -new -key /etc/pki/CA/private/xxx001-ca01.key -subj "/C=JP/ST=Kanagawa/O=xxx/CN=xxx001-ca" -sha256 -out /etc/pki/CA/xxx001-cacert01.csr
```

CAのリクエストに自己署名。100年いっちゃいましょう。

https://docs.openssl.org/master/man1/openssl-x509/

```
openssl x509 -days 36500 -in /etc/pki/CA/xxx001-cacert01.csr -req -signkey /etc/pki/CA/private/xxx001-ca01.key -out /etc/pki/CA/certs/xxx001-cacert01.pem
```

認証局の証明書が準備できたので、証明書の発行準備をします。

```
touch /etc/pki/CA/index.txt
echo '1000' > /etc/pki/CA/serial
echo '1000' > /etc/pki/CA/crlnumber
```

---

### サーバ証明書

次はサーバ証明書を作ります。

CAのキーとは別に作成した `/path/to/the.key` を `/etc/pki/tls/private/xxx001-servercert.key` にコピーするなりキー作成でいきなり作るなりしておきます。

リクエストします

```
openssl req -new -key /etc/pki/tls/private/xxx001-servercert.key -subj "/C=JP/ST=Kanagawa/O=xxx/CN=*.xxx.com" -sha256 -reqexts SAN -config <(printf "distinguished_name=a\n[a]\n[SAN]\nsubjectAltName=DNS:*.xxx.com") -out /etc/pki/tls/xxx001-servercert.csr
```

10年で署名します。これは100年以内だったら何年でもいいんですが…

https://docs.openssl.org/master/man1/openssl-ca/

```
openssl ca -days 3650 -in /etc/pki/tls/xxx001-servercert.csr -out /etc/pki/tls/certs/xxx001-servercert.pem -keyfile /etc/pki/CA/private/xxx001-ca01.key -cert /etc/pki/CA/certs/xxx001-cacert01.pem -extfile <(printf "subjectAltName=DNS:*.xxx.com")
```

---

### s_client を使った証明書確認の方法

`s_client` を使った証明書確認の方法をちょっとだけ説明します。

ドキュメントはこちら。

https://docs.openssl.org/master/man1/openssl-s_client/

オプションが多くて驚きますが、普通は `-connect` と `-showcerts` ぐらいしか使わないと思います。

使用例: 

```
openssl s_client -connect www.example.com:443 -showcerts
```

---

### その他

ちなみに楕円曲線暗号についてさらっと知っておきたい方にはこちらが参考になるかと思います。

https://blog.cloudflare.com/ja-jp/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/