OpenSSLを使ってオレオレ証明書作成してみる

勉強のためにオレオレ証明書を作成した時のメモ

# 参考

+ [チュートリアル: Amazon Linux で SSL/TLS を使用できるように Apache ウェブサーバーを設定する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/SSL-on-an-instance.html)
+ [食べる！SSL！　―HTTPS環境構築から始めるSSL入門](http://www.amazon.co.jp/%E9%A3%9F%E3%81%B9%E3%82%8B%EF%BC%81SSL%EF%BC%81-%E2%80%95HTTPS%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%8B%E3%82%89%E5%A7%8B%E3%82%81%E3%82%8BSSL%E5%85%A5%E9%96%80-%E5%B0%8F%E5%B3%B6-%E6%8B%93%E4%B9%9F-ebook/dp/B00PHC4480)

# 環境

+ Amazon Linux AMI 2016.03
+ OpenSSL 1.0.1k-fips 8 Jan 2015
+ Apache httpd2.4 + mod_ssl


# 初期状態でとりあえずやってみる

```bash
# インストール
$sudo yum install httpd24 mod24_ssl -y

# 起動
$sudo service httpd start
```

実はAmazonLinuxではこれでhttps通信が既にできます。
HTTPS通信をするために秘密鍵と証明書が必要ですが、AmazonLinuxでは起動時に自動でそれらが生成されるためです。
また、httpdのSSLの設定を記述する設定ファイル`/etc/httpd/conf.d/ssl.conf`に自動作成されたファイルのパスが最初から書いてあるので特に変更の必要などはなく起動するだけでOKとなります。

+ /etc/pki/tls/private/localhost.key->自動生成された2048ビットのRSA秘密鍵
+ /etc/pki/tls/certs/localhost.crt->自己署名のX.509証明書

# 手動でやってみる

デフォルトのものだけ使っても面白くないので、自分で秘密鍵、CSR、証明書を作成していみます。
CSRとは証明書を作成するために必要なファイルです。

## 秘密鍵の作成

```bash
# RSA秘密鍵(2048 bit)の生成
$sudo sh -c "openssl genrsa 2048 > /etc/httpd/conf/server.key"
Generating RSA private key, 2048 bit long modulus
...................................+++
........+++
e is 65537 (0x10001)

# 確認.Base64形式でエンコードされた文字列
$cat /etc/httpd/conf/server.key
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAnSFYWDTjmMfay1ywLRX+fue/c/yANr5rki8/CYtYTT
・・・(中略)
diNy6NiYRgRb8Tvu7e5K+KwfN4g4NjxpbmocpDVRpC6eVFa5okTb
-----END RSA PRIVATE KEY-----

# デコードして確認
$openssl rsa -text < /etc/httpd/conf/server.key
Private-Key: (2048 bit)
modulus:
    00:9d:21:58:58:34:e3:98:c7:da:cb:5c:b0:2d:15:
    fe:7e:e7:bf:73:fc:80:36:be:6b:92:2f:3f:09:8b:
    58:4d:3e:dc:e8:72:7f:65:08:a4:af:ad:19:50:da:
    6c:1d:93:91:a3:f0:67:ed:19:58:5b:ca:96:cb:b1:
    d9:80:65:a9:cc:82:a4:92:a2:73:56:ae:70:aa:f3:
    f8:83:c4:51:e5:3c:65:4d:d3:b7:1a:2a:e4:35:b4:
    43:d0:e4:6b:64:75:cb:5a:6b:32:71:d7:03:94:68:
    fe:5d:f1:3a:b4:83:f7:c0:a8:bf:0c:7a:cc:40:50:
    11:19:ed:b7:43:56:ff:15:5f:97:0c:ca:11:f8:aa:
    7b:0c:b7:80:75:02:c1:66:c5:26:51:5f:5a:70:a0:
    b6:30:2c:45:28:84:a8:11:87:30:71:64:3b:b5:52:
    4c:0f:58:cd:15:4d:df:12:53:15:a8:c2:92:88:b2:
    c4:71:be:50:0e:f1:28:6d:a1:2d:a7:fe:82:53:42:
    4c:4e:cf:99:8e:79:28:bd:43:7a:13:57:7d:4c:e3:
    2c:77:e2:67:32:db:ba:59:ea:d6:45:b0:9c:12:97:
    13:1a:11:f7:92:96:4c:33:d8:24:ef:12:23:6d:90:
    f0:3b:a8:d0:94:40:ff:69:7e:ae:d0:d2:44:55:0a:
    6a:01
publicExponent: 65537 (0x10001)
privateExponent:
    18:f3:00:7a:10:fb:ca:78:81:4f:25:0a:7c:3e:2f:
    c8:aa:b7:85:8d:24:36:8d:09:bb:8e:70:ed:ed:08:
(以降略)
```

これで秘密鍵ができました。
秘密鍵ということは公開鍵も作成する必要がある気がしますが、必要ありません。というのも上記秘密鍵情報の中に公開鍵情報が「modules」、「publicExponent」として記述されているためです。


## CSRの作成

秘密鍵を利用してCSR(Certificate Signing Request)を作成します。CSRはCertificate signing requestということで証明書の作成依頼を行う際に必要です。
色々聞かれるので適当に回答します。

```bash
# 秘密鍵を利用してCSRを作成
$sudo sh -c "openssl req -new -key /etc/httpd/conf/server.key > /etc/httpd/conf/server.csr"

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:Minato-ku
Organization Name (eg, company) [Default Company Ltd]:company
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:ec2-52-192-179-233.ap-northeast-1.compute.amazonaws.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```

作成できたか確認します。

```bash
# 確認(エンコード)
$cat /etc/httpd/conf/server.csr
-----BEGIN CERTIFICATE REQUEST-----
MIICyzCCAbMCAQAwgYUxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzESMBAG
(中略)
v3GSxQpANY8xQmnQfRDQtm/nurFhgPoKgxk80qiztADaPOg97bG7qmgIFvPTih4=
-----END CERTIFICATE REQUEST-----

# 確認(デコード)
$openssl req -text < /etc/httpd/conf/server.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=JP, ST=Tokyo, L=Minato-ku, O=company, CN=ec2-52-192-179-233.ap-northeast-1.compute.amazonaws.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:9d:21:58:58:34:e3:98:c7:da:cb:5c:b0:2d:15:
                    fe:7e:e7:bf:73:fc:80:36:be:6b:92:2f:3f:09:8b:
                    58:4d:3e:dc:e8:72:7f:65:08:a4:af:ad:19:50:da:
                    6c:1d:93:91:a3:f0:67:ed:19:58:5b:ca:96:cb:b1:
                    d9:80:65:a9:cc:82:a4:92:a2:73:56:ae:70:aa:f3:
                    f8:83:c4:51:e5:3c:65:4d:d3:b7:1a:2a:e4:35:b4:
                    43:d0:e4:6b:64:75:cb:5a:6b:32:71:d7:03:94:68:
                    fe:5d:f1:3a:b4:83:f7:c0:a8:bf:0c:7a:cc:40:50:
                    11:19:ed:b7:43:56:ff:15:5f:97:0c:ca:11:f8:aa:
                    7b:0c:b7:80:75:02:c1:66:c5:26:51:5f:5a:70:a0:
                    b6:30:2c:45:28:84:a8:11:87:30:71:64:3b:b5:52:
                    4c:0f:58:cd:15:4d:df:12:53:15:a8:c2:92:88:b2:
                    c4:71:be:50:0e:f1:28:6d:a1:2d:a7:fe:82:53:42:
                    4c:4e:cf:99:8e:79:28:bd:43:7a:13:57:7d:4c:e3:
                    2c:77:e2:67:32:db:ba:59:ea:d6:45:b0:9c:12:97:
                    13:1a:11:f7:92:96:4c:33:d8:24:ef:12:23:6d:90:
                    f0:3b:a8:d0:94:40:ff:69:7e:ae:d0:d2:44:55:0a:
                    6a:01
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         49:c9:be:1d:4c:de:dc:f7:19:df:ff:96:1b:49:ff:08:62:ed:
         51:d6:a1:08:be:50:cf:0d:45:89:98:77:cd:67:92:9b:84:a7:
         91:43:b5:ec:88:e6:97:b4:3d:18:c5:d4:6c:72:c3:51:c1:5d:
         d8:6d:4a:84:d3:55:8f:87:52:28:fb:a8:41:a8:58:bf:2c:18:
         d3:25:94:07:67:cb:26:e4:3c:13:45:db:5f:34:97:82:db:03:
         07:9e:b3:0e:21:7d:09:d9:df:df:11:98:7f:44:f2:4e:15:2f:
         cf:73:13:05:ee:59:37:21:69:ba:14:c0:f9:d2:ad:fc:2c:0a:
(略)
```

「Subject Public Key Info」にはCSR作成の際の標準入力に指定した秘密鍵から取り出した公開鍵情報が記載されています。確かに先ほど秘密鍵をデコードしたときの「module 」と「Exponent(Public Exponent)」の部分と同じ値になっていますね。

「Signature Algorithm: sha256WithRSAEncryption」と書いてあるので公開鍵暗号方式にRSA、ハッシュ関数にSHA-256を利用している事を意味します。

## 証明書の作成

本来なら先ほど作成したCSRを認証局（ベリサインなど）に送付して第3者に証明書を作成してもらうのですが、今回は自分で証明書を作成します。(いわゆるオレオレ証明書)

```bash
# X.509の自己証明書を作成
$openssl x509 -req -signkey /etc/httpd/conf/server.key < /etc/httpd/conf/server.csr > server.crt
Signature ok
subject=/C=JP/ST=Tokyo/L=Minato-ku/O=company/CN=ec2-52-192-179-233.ap-northeast-1.compute.amazonaws.com
Getting Private key

# 確認(エンコード)
$cat server.crt
-----BEGIN CERTIFICATE-----
MIIDiDCCAnACCQDcDDvPiQWGbjANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMC
(中略)
rTFXDA2Y2xX/zLCRKMs5lOjBhIIjhz8LWyTlHqD9UEVA40qiufFKVH32z4o=
-----END CERTIFICATE-----

# 確認(デコード)
$openssl x509 -text < server.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 15856114150607783534 (0xdc0c3bcf8905866e)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, L=Minato-ku, O=company, CN=ec2-52-192-179-233.ap-northeast-1.compute.amazonaws.com
        Validity
            Not Before: Mar 25 08:45:49 2016 GMT
            Not After : Apr 24 08:45:49 2016 GMT
        Subject: C=JP, ST=Tokyo, L=Minato-ku, O=company, CN=ec2-52-192-179-233.ap-northeast-1.compute.amazonaws.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:9d:21:58:58:34:e3:98:c7:da:cb:5c:b0:2d:15:
                    fe:7e:e7:bf:73:fc:80:36:be:6b:92:2f:3f:09:8b:
                    58:4d:3e:dc:e8:72:7f:65:08:a4:af:ad:19:50:da:
                    6c:1d:93:91:a3:f0:67:ed:19:58:5b:ca:96:cb:b1:
                    d9:80:65:a9:cc:82:a4:92:a2:73:56:ae:70:aa:f3:
                    f8:83:c4:51:e5:3c:65:4d:d3:b7:1a:2a:e4:35:b4:
                    43:d0:e4:6b:64:75:cb:5a:6b:32:71:d7:03:94:68:
                    fe:5d:f1:3a:b4:83:f7:c0:a8:bf:0c:7a:cc:40:50:
                    11:19:ed:b7:43:56:ff:15:5f:97:0c:ca:11:f8:aa:
                    7b:0c:b7:80:75:02:c1:66:c5:26:51:5f:5a:70:a0:
                    b6:30:2c:45:28:84:a8:11:87:30:71:64:3b:b5:52:
                    4c:0f:58:cd:15:4d:df:12:53:15:a8:c2:92:88:b2:
                    c4:71:be:50:0e:f1:28:6d:a1:2d:a7:fe:82:53:42:
                    4c:4e:cf:99:8e:79:28:bd:43:7a:13:57:7d:4c:e3:
                    2c:77:e2:67:32:db:ba:59:ea:d6:45:b0:9c:12:97:
                    13:1a:11:f7:92:96:4c:33:d8:24:ef:12:23:6d:90:
                    f0:3b:a8:d0:94:40:ff:69:7e:ae:d0:d2:44:55:0a:
                    6a:01
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha1WithRSAEncryption
         3b:21:bc:2d:d7:c8:4a:62:a6:11:ba:95:40:b3:8e:fd:0b:d8:
         62:f7:e4:72:67:10:8f:99:cb:12:c2:18:c3:b9:dc:14:8a:1f:
         0c:e5:4d:7c:06:43:57:e8:27:d0:99:5a:36:07:10:a2:1c:5a:
         58:dc:f2:f4:08:f6:be:55:c2:b4:01:10:a3:8f:8d:d1:e1:cd:
         1e:2a:b2:83:66:e7:25:e2:4c:39:1e:9a:17:28:d4:6b:09:24:
         de:b8:f7:48:20:2e:9c:58:d5:df:dd:26:61:1f:f8:1f:4d:65:
         9c:2a:19:68:2e:1c:6b:e0:01:eb:9c:cd:f3:e8:f1:53:b4:cd:
         9c:b2:2a:7f:92:2b:24:83:d9:43:3c:58:00:db:f1:e9:71:56:
         98:44:cb:37:7d:92:98:b5:fd:5d:96:0d:f3:68:29:fe:66:2a:
         21:e8:e2:ed:d0:43:d6:81:42:7e:41:52:5a:7c:6a:07:65:22:
         ae:51:fe:c1:fe:c2:c2:4c:63:05:c1:81:65:47:a2:d4:d1:22:
         8f:6d:be:f8:72:10:b2:6e:11:f0:58:13:a7:88:ad:31:57:0c:
         0d:98:db:15:ff:cc:b0:91:28:cb:39:94:e8:c1:84:82:23:87:
         3f:0b:5b:24:e5:1e:a0:fd:50:45:40:e3:4a:a2:b9:f1:4a:54:
         7d:f6:cf:8a
-----BEGIN CERTIFICATE-----
MIIDiDCCAnACCQDcDDvPiQWGbjANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMC
(中略)
rTFXDA2Y2xX/zLCRKMs5lOjBhIIjhz8LWyTlHqD9UEVA40qiufFKVH32z4o=
-----END CERTIFICATE-----
```

## 確認

必要なファイルは作成できたのでhttpdの設定ファイルで秘密鍵、証明書のパスを指定する部分を今回作成したファイルパスに変更します。

```/etc/httpd/conf.d/ssl.conf
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /etc/httpd/conf/server.crt

#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /etc/httpd/conf/server.key
```

httpdを再起動してみます。

```bash
$sudo service httpd restart
```

再起動後、ブラウザでアクセスしてみると証明書の記述が先ほど指定した内容に変更されていることが確認できました。

![Screen Shot 2016-03-26 at 4.10.47 PM.png](https://qiita-image-store.s3.amazonaws.com/0/20193/2b85b2ff-9418-91e5-82f8-d21a704f83ee.png "Screen Shot 2016-03-26 at 4.10.47 PM.png")