Chrome58以降でハネられないSHA-2でオレオレ認証局署名のあるオレオレ証明書

## 0. 想定環境

サーバ
- Ubuntu 14.04
- Apache 2.4.*

クライアント
- Windows 7
- Chrome
- Firefox

※ 想定環境外でも大枠ではほぼ同じと思われるので、それぞれの環境に読み替えて読んでいただければ。


## 1. 環境設定

### 1-1. オレオレ認証局用ディレクトリ生成
/etc/ssl（または環境にあわせた対象ディレクトリ）で作業

```
cd /etc/ssl
mkdir myCA
cd myCA
mkdir newcerts
mkdir certs
mkdir crl
mkdir private
chmod 700 private
```

`myCA` はお好みのディレクトリ名で大丈夫です。
変更した場合、以降の `myCA` はすべてそのディレクトリ名で読み替えてください。

### 1-2. オレオレ証明局の運用に必要なファイルの生成
/etc/ssl/myCA（前項で作成した対象ディレクトリ）で作業

```
touch index.txt
echo 00 |tee serial
```


## 2. openssl.cnf

### 2-1. openssl.cnf編集
/etc/ssl（または環境にあわせた対象ディレクトリ）にあるはず

```openssl.conf
[ CA_default ]
dir = /etc/ssl/myCA # または1-1.で作成した対象ディレクトリ
certificate = $dir/ca.crt # 次項で作成
private_key = $dir/ca.key # 次項で作成

x509_extensions = usr_cert # 初期設定ママ

[ usr_cert ]
subjectAltName = @alt_names

[ req ]
req_extensions = v3_req

[ v3_req ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ssl.test
DNS.2 = *.ssl.test # localhostはサブドメイン使えないので注意
```

*（2018/08/25更新：テスト用として書いていたドメイン .local を正しくテスト用として確保されている .test に変更）*

`[CA_default]` の `x509_extensions =` を `v3_req` として合流してしまう方法もあるようなのですが、認証局と証明書の設定が同じで良いのか不安があり、知識不足のためバラのままとしてあります。


## 3. オレオレ証明局

### 3-1. オレオレ証明局の秘密鍵と証明書ファイルを作成

```
openssl req -new -x509 -sha256 -days 36500 -newkey rsa:4096 -out ca.crt -keyout private/ca.key
```

##### コマンドラインオプションの簡単な説明  
- openssl req　署名要求ファイルを生成する
- -new　新しい署名要求ファイルの生成を行う
- -x509　X.509形式の自己署名証明書ファイルを作成　※ このオプションを使うことで、署名要求ファイル `csr`  ではなく証明書ファイル `crt` の生成になる
- -sha256　ハッシュ形式の指定  
- -days　36500 署名要求ファイルの有効期限の指定。うるう年を考慮していないので36500ではぴったり100年にはならない  
- -newkey　rsa:4096 秘密鍵ファイルを新規作成  
- -out　ca.crt 出力先ファイル名の指定  
- -keyout　private/ca.key 秘密鍵ファイルの出力先ファイル名の指定

### 3-2. 秘密鍵のパスフレーズ解除
```
openssl rsa -in private/ca.key -out private/ca.key
```


## 4. サーバ証明書

### 4-1. サーバ証明書の秘密鍵と署名要求ファイルを作成
```
openssl req -new -sha256 -days 36500 -newkey rsa:4096 -out server.csr -keyout private/server.key
```


### 4-2. 秘密鍵のパスフレーズ解除
```
openssl rsa -in private/server.key -out private/server.key
```


## 5. オレオレ認証局署名済みのサーバ証明書発行
```diff
openssl ca -days 36500 -keyfile private/ca.key -cert ca.crt -in server.csr -out server.crt
```


## 6. Webサーバ設定（Apacheの場合）
/etc/apache2/sites-available/ssl.conf を編集

```ssl.conf
<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerAdmin webmaster@ssl.test
        ServerName ssl.test
        DocumentRoot /var/www/public_html/ssl.test

        (略)

        SSLEngine on
        SSLCertificateFile /etc/ssl/myCA/server.crt
        SSLCertificateKeyFile /etc/ssl/myCA/private/server.key

        (略)

    </VirtualHost>
</IfModule>
```

*（2018/08/25更新：テスト用として書いていたドメイン .local を正しくテスト用として確保されている .test に変更）*

`a2enmod ssl` と `a2ensite ssl` と `service apache2 reload` も忘れずに。



## 7. クライアントに証明書インストール

`ca.crt` を「信頼されたルート証明書」としてインストールすれば、HTTPSで保護された通信として緑色の鍵マークのついた接続が可能です。

ChromeはOSが持っている証明書リストを利用するようなので、証明書ファイルをダブルクリックでインストールすればOKです。

Firefoxは独自に証明書リストを持っているようなので、オプションの詳細 - 証明書 - 証明書を表示 から　認証局証明書 - インポート してあげればOKです。

IE11でも動いたのでだいたい大丈夫じゃないかと。


## #. （補足）openssl出力ファイルの内容確認方法

秘密鍵ファイル

```
openssl rsa -text private/ca.key
openssl rsa -text private/server.key
```

証明書ファイル

```
openssl x509 -text -in ca.crt
openssl x509 -text -in server.crt
```

対象サーバの対象ポートに接続して確認

```
openssl s_client -connect ssl.test:443 -showcerts
```

*（2018/08/25更新：テスト用として書いていたドメイン .local を正しくテスト用として確保されている .test に変更）*



## ##. （補足2）不特定多数に配布するためには専用の形式がある

不特定多数のユーザーにアクセスしてもらうために `crt` を直接配布してはいけない。
配布用の形式 `der` があるので、変換したものを配布する。

```
openssl x509 -inform PEM -in ca.crt -outform DER -out ca.der
```

※ こちらは筆者未確認です。


## ###. 参考資料

[オレだよオレオレ認証局で証明書つくる - Qiita](http://qiita.com/ll_kuma_ll/items/13c962a6a74874af39c6)

[SHA-2でSANsな自己発行証明書の作成 - Qiita](http://qiita.com/tanakachang/items/c4cf9d55c8e36ac46610)

[お前らのSSH Keysの作り方は間違っている - Qiita](http://qiita.com/suthio/items/2760e4cff0e185fe2db9)

[SSL証明書設定でよくやってることをまとめる。 - Qiita](http://qiita.com/NakashimaKeisuke_zerodaynet/items/bfc77e5fe98b587532d0)

[オレオレ証明書をopensslで作る（詳細版） - ろば電子が詰まっている](http://d.hatena.ne.jp/ozuma/20130511/1368284304)

[opensslコマンドで認証局(CA)を構築してサーバ証明書を発行する - 無題の備忘録](http://stacktrace.hatenablog.jp/entry/2015/12/12/102945)

[OpenSSLで自己認証局と証明書の作成 - bnote](http://www.bnote.net/kuro_box/self_ca.shtml)