SSL/TLS の導入 (1)

前へ << 暗号化のお話 (5) SSL/TLS の導入 (2) >> 次へ

全体の流れ

まず、SSL/TLS を導入するために何が必要なのかをまとめておきます。 それぞれの作業を「誰が」行うのかを意識してください。
  1. サーバ管理者が RSA 秘密鍵を生成します。
  2. サーバ管理者が RSA 秘密鍵を元に CSR (Certificate Signing Request: 証明書要求) ファイルを生成し、認証局に送付します。
  3. 認証局が受け取った CSR を元にサーバ証明書を生成し、サーバ管理者に送付します。
  4. サーバ管理者は受け取ったサーバ証明書を Web サーバに組み込みます。
登場人物は「サーバ管理者」と「認証局」がいます。 「サーバ管理者」は「Web サーバに SSL/TLS を導入したい人」です。 「認証局」は VeriSign など、証明書を発行している企業です。

RSA 秘密鍵生成

まずはじめに、OpenSSL で RSA 秘密鍵を作成します。 root 権限は不要です。カレントディレクトリにファイルを作成するだけですので、 作業ディレクトリも適当な場所で構いません。

以下の例では 1024bit の RSA 秘密鍵を生成し、server.key というファイルに出力しています。

% openssl genrsa -out server.key 1024
Generating RSA private key, 1024 bit long modulus
............................++++++
.........++++++
e is 65537 (0x10001)
パスワードなどは求められません。RSA における鍵は素数であり、 素数選択は全て OpenSSL がよきにはからってくれます。 ファイル名は何でもよいです。server.key としているのは、 このファイルを最終的に Apache が参照するのですが、 Apache の設定ファイルにデフォルトで server.key と記述されているので、 それにあわせただけです。
秘密鍵を同じサーバ内のユーザに見られないように、作成後はすぐに
% chmod 400 server.key
とパーミッションを落としておきましょう。
server.key の内容は以下のようなテキストファイルになります。
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC233bDH7GNAgRLKv7xgcx05in0aoJo60nJEkrkSrT6fXaA7CkB
Vtv4upDR6bf7zhQRcB4rVTT489HBoDjal7zGKRygVMZzIVOQbGoNIKef3mFk7aJm
k7++Cs3Y3s+cI1HtoV3Qq+ynufJkJITXeEBOB5x4zmizdwlYd7f00noRzQIDAQAB
AoGATK32xmqLsGygEES/EdUzPfEktm/Srtu53K3m6ULKEB57iiN8LiuVoP3Zq6ss
klEe6RDyFYls5NaXpXDhZgcqB9fKcjwtuGoTXKvoGs2FS6vQoIiTMuihbOzUq4mb
oMPUk78iDqGVNq8ZqybsSdcAy217jjpzthngLzEUVZBN0KECQQDcMVD060lNE5K5
93WscNFKCxst0R8S3fca4a/hnNTyduexH0W5yfxL9FSHy1jNKPRau5ndhuDA3BzK
dGRH/gwHAkEA1JyEJv4S4G/saeNv+hBD8vI7gOHKta5gVHHIkTdzgIyzB6qNmEtu
8ri63pySPP2KlL277o3AZoX8F/QhrRumiwJASGvD97oHMt2ULawRPPUiMNs0Rj54
nOj6ZBIEmgzOES1AiQYDFdc0LvsebkdYXqnwrIL1WWIKPARpR8E+VltdMwJBAMk2
97sPaj4Orufn3+oBysz6g2YOSxJ23aQNq4wDtsRKZIU03JzthysfuXtFIwGl0qnC
h0HV1ekxlMv2uIhkStECQBxNx/BGxEXq8b148gQBYVfynSFDI6JiLG+gGgIZjUJq
+JRzMeNt5aDNFpUZYUc+PfzJNg1hftHPgkO8bWTXorA=
-----END RSA PRIVATE KEY-----
これは PEM 形式というフォーマットで、1行目と最終行の
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
も規格化されています。このファイルを直接修正する必要はありません。 下手にいじらないようにしましょう。
PEM (Privacy Enhancement for Internet Electronic Mail) は RFC 1421RFC 1422RFC 1423RFC 1424 にて定義されています。
内容を見たい場合は、openssl rsa で確認できます。
% openssl rsa -in server.key -text -noout
Private-Key: (1024 bit)
modulus:
    00:b6:df:76:c3:1f:b1:8d:02:04:4b:2a:fe:f1:81:
    cc:74:e6:29:f4:6a:82:68:eb:49:c9:12:4a:e4:4a:
    b4:fa:7d:76:80:ec:29:01:56:db:f8:ba:90:d1:e9:
    b7:fb:ce:14:11:70:1e:2b:55:34:f8:f3:d1:c1:a0:
    38:da:97:bc:c6:29:1c:a0:54:c6:73:21:53:90:6c:
    6a:0d:20:a7:9f:de:61:64:ed:a2:66:93:bf:be:0a:
    cd:d8:de:cf:9c:23:51:ed:a1:5d:d0:ab:ec:a7:b9:
    f2:64:24:84:d7:78:40:4e:07:9c:78:ce:68:b3:77:
    09:58:77:b7:f4:d2:7a:11:cd
publicExponent: 65537 (0x10001)
privateExponent:
    4c:ad:f6:c6:6a:8b:b0:6c:a0:10:44:bf:11:d5:33:
    (略)
prime1:
    00:dc:31:50:f4:eb:49:4d:13:92:b9:f7:75:ac:70:
    (略)
prime2:
    00:d4:9c:84:26:fe:12:e0:6f:ec:69:e3:6f:fa:10:
    (略)
exponent1:
    48:6b:c3:f7:ba:07:32:dd:94:2d:ac:11:3c:f5:22:
    (略)
exponent2:
    00:c9:36:f7:bb:0f:6a:3e:0e:ae:e7:e7:df:ea:01:
    (略)
coefficient:
    1c:4d:c7:f0:46:c4:45:ea:f1:bd:78:f2:04:01:61:
    (略)
各項目の意味は以下の通りです (説明は 暗号化のお話 (2) を参照)。
  • modules: RSA 構造体の n に相当 (p*q)
  • publicExponent: RSA 構造体の e に相当
  • privateExponent: RSA 構造体の d に相当
  • prime1: RSA 構造体の p に相当 (素数)
  • prime2: RSA 構造体の q に相当 (素数)
  • exponent1: RSA 構造体の dmp1 に相当 (d mod (p-1))
  • exponent2: RSA 構造体の dmq1 に相当 (d mod (q-1))
  • cofficient: RSA 構造体の iqmp に相当 ((q-1) mod p)
RSA 秘密鍵の内容は全て素数などの数値であることがわかります。 RSA のセキュリティは「n を素因数分解して、素数 p とq を求めることが非常に困難」 という一点で成り立っています。 しかし上記ファイルには素数 p と q がばっちり記述されています。 ですから、このファイルは絶対に公開してはいけません。

openssl genrsa を実行するたびに、生成される RSA 秘密鍵の内容は異なります (乱数を利用している)。 もし生成された素数が気に入らなければ、何度も genrsa を実行して秘密鍵の生成を繰り返しても構いません。 ただし認証局に CSR (証明書要求) を送付してしまった後に秘密鍵をなくしてしまうと、 再度認証のやりなおしになります。

CSR 生成

生成した RSA 秘密鍵 server.key を元に、CSR (証明書要求) を作成し、csr.pem に出力します。 ここでは SSL/TLS を導入したいドメインの情報を入力します。

% openssl req -new -key server.key -out csr.pem -sha1
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) [AU]:JP
	⇒ 2文字の国名コード
State or Province Name (full name) [Some-State]:Kanagawa
	⇒ 都道府県名
Locality Name (eg, city) []:Kawasaki
	⇒ 市区町村名
Organization Name (eg, company) [Internet Widgits Pty Ltd]:68user's page
	⇒ 企業名
Organizational Unit Name (eg, section) []:(ENTER)
	⇒ 部署名 (オプション)
Common Name (eg, YOUR name) []:X68000.q-e-d.net
	⇒ SSL/TLS を導入するドメイン名 (http://XXXX/ の XXXX)
Email Address []:
	⇒ メールアドレス (オプション)

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:(ENTER)
	⇒ パスワード (オプション)
An optional company name []:(ENTER)
	⇒ 企業名の略称 (オプション)
生成される csr.pem の内容は以下の通りです。
-----BEGIN CERTIFICATE REQUEST-----
MIIBpjCCAQ8CAQAwZjELMAkGA1UEBhMCSlAxETAPBgNVBAgTCEthbmFnYXdhMREw
DwYDVQQHEwhLYXdhc2FraTEWMBQGA1UEChMNNjh1c2VyJ3MgcGFnZTEZMBcGA1UE
AxMQWDY4MDAwLnEtZS1kLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
tt92wx+xjQIESyr+8YHMdOYp9GqCaOtJyRJK5Eq0+n12gOwpAVbb+LqQ0em3+84U
EXAeK1U0+PPRwaA42pe8xikcoFTGcyFTkGxqDSCnn95hZO2iZpO/vgrN2N7PnCNR
7aFd0Kvsp7nyZCSE13hATgeceM5os3cJWHe39NJ6Ec0CAwEAAaAAMA0GCSqGSIb3
DQEBBQUAA4GBALDyJo9LuyjdfL2BalWdFmN0ryBqsXgmscx7101ZSX4L1/w7kuNZ
KrM2FnUK4uVmKMbXZPjhgbXfEq6GC0/Zvn70XznH3g7UiWJTIo9HpJVM/djm4rkB
HZLx0hy0inB1Xno3uJoVq5DXO6wVYNJBhgqFfT/T4R1bBGCAsWq894fj
-----END CERTIFICATE REQUEST-----
(RSA 秘密鍵と、入力する文字列が同じであれば) CSR は必ず同じものが生成されます。

CSR の内容を確認するには openssl req を使います。

% openssl req -in csr.pem -text -noout
    Data:
        Version: 0 (0x0)
        Subject: C=JP, ST=Kanagawa, L=Kawasaki, O=68user's page, CN=X68000.q-e-d.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:b6:df:76:c3:1f:b1:8d:02:04:4b:2a:fe:f1:81:
                    cc:74:e6:29:f4:6a:82:68:eb:49:c9:12:4a:e4:4a:
                    b4:fa:7d:76:80:ec:29:01:56:db:f8:ba:90:d1:e9:
                    b7:fb:ce:14:11:70:1e:2b:55:34:f8:f3:d1:c1:a0:
                    38:da:97:bc:c6:29:1c:a0:54:c6:73:21:53:90:6c:
                    6a:0d:20:a7:9f:de:61:64:ed:a2:66:93:bf:be:0a:
                    cd:d8:de:cf:9c:23:51:ed:a1:5d:d0:ab:ec:a7:b9:
                    f2:64:24:84:d7:78:40:4e:07:9c:78:ce:68:b3:77:
                    09:58:77:b7:f4:d2:7a:11:cd
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
        b0:f2:26:8f:4b:bb:28:dd:7c:bd:81:6a:55:9d:16:63:74:af:
        20:6a:b1:78:26:b1:cc:7b:d7:4d:59:49:7e:0b:d7:fc:3b:92:
        e3:59:2a:b3:36:16:75:0a:e2:e5:66:28:c6:d7:64:f8:e1:81:
        b5:df:12:ae:86:0b:4f:d9:be:7e:f4:5f:39:c7:de:0e:d4:89:
        62:53:22:8f:47:a4:95:4c:fd:d8:e6:e2:b9:01:1d:92:f1:d2:
        1c:b4:8a:70:75:5e:7a:37:b8:9a:15:ab:90:d7:3b:ac:15:60:
        d2:41:86:0a:85:7d:3f:d3:e1:1d:5b:04:60:80:b1:6a:bc:f7:
        87:e3
CSR 作成時に入力した内容と、RSA 秘密鍵の Modulus と Exponent (n と e)、 そして秘密鍵のハッシュが含まれています。 デフォルトではハッシュ関数に MD5 が使用されますが、CSR 作成時に -sha1 オプションを付けて、 SHA1 を使うようにしています。
MD5 は 2004年に衝突 (コリジョン) が発見されました。 強衝突耐性が破られただけですので、実用上はまだ問題はないかもしれませんが、 現時点では SHA-1 を使っておく方が無難でしょう。

この CSR は認証局に送付するものですが、 広く一般に公開しても構いません (公開してもメリットは一切ありませんが)。

署名

次に、証明書を発行します。本来はこれは VeriSign などの認証局の仕事なのですが、 ここでは自分で署名する「自己署名」というやり方を紹介します。
証明書を簡単に説明すると、「サーバ管理者が作成した公開鍵」に対して、 「認証局の秘密鍵」で暗号化したもののことです。

認証局の秘密鍵は認証局しか知りません。 一方、認証局の公開鍵は誰でも知っています (あらかじめブラウザに入ってます)。 秘密鍵と公開鍵はペアのはずですから、証明書は認証局の公開鍵で復号化できるはずです。 もし証明書を復号化できたら、「その証明書は確かに認証局の秘密鍵で暗号化されている」 と言えます。これが署名の検証です。

署名を行うには openssl x509 を使用します。ポイントは以下のとおり。
  • 入力ファイル (CSR) に csr.pem を指定します。
  • 出力ファイル (証明書) に server.crt を指定します。
  • openssl x509 のデフォルトでは、入力ファイル形式は X.509 証明書となっているので、 -req オプションを付けて入力ファイルが CSR であることを指定します。
  • -signkey は自己署名用のオプションで、その直後に RSA 秘密鍵のファイル (openssl genrsa で生成したファイル) を指定します。
  • 自己署名の場合は証明書の有効期間がデフォルトでは 1ヵ月となりますので、 ここでは -days 365 として 1年間にしています。
  • MD5 でなく SHA-1 で署名するために、-sha1 オプションを付けています。
% openssl x509 -in csr.pem -out server.crt -req -signkey server.key -days 365 -sha1
Signature ok
subject=/C=JP/ST=Kanagawa/L=Kawasaki/O=68user's page/CN=X68000.q-e-d.net
Getting Private key
生成された server.crt の内容は以下のようになります。
-----BEGIN CERTIFICATE-----
MIICOzCCAaQCAQAwDQYJKoZIhvcNAQEFBQAwZjELMAkGA1UEBhMCSlAxETAPBgNV
BAgTCEthbmFnYXdhMREwDwYDVQQHEwhLYXdhc2FraTEWMBQGA1UEChMNNjh1c2Vy
J3MgcGFnZTEZMBcGA1UEAxMQWDY4MDAwLnEtZS1kLm5ldDAeFw0wNTAzMTkxODI3
MzNaFw0wNjAzMTkxODI3MzNaMGYxCzAJBgNVBAYTAkpQMREwDwYDVQQIEwhLYW5h
Z2F3YTERMA8GA1UEBxMIS2F3YXNha2kxFjAUBgNVBAoTDTY4dXNlcidzIHBhZ2Ux
GTAXBgNVBAMTEFg2ODAwMC5xLWUtZC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
MIGJAoGBALbfdsMfsY0CBEsq/vGBzHTmKfRqgmjrSckSSuRKtPp9doDsKQFW2/i6
kNHpt/vOFBFwHitVNPjz0cGgONqXvMYpHKBUxnMhU5Bsag0gp5/eYWTtomaTv74K
zdjez5wjUe2hXdCr7Ke58mQkhNd4QE4HnHjOaLN3CVh3t/TSehHNAgMBAAEwDQYJ
KoZIhvcNAQEFBQADgYEAOYDxzPcMj3i0MFnl0Bt0jpTUcPefZ/zxjDgW5E+8W3oy
8XDaRhsYyYRoFpsxHXi4cuPJOAL8+PT2z5m6vuYAFbgcuLnt5QumaAOIvYM757dO
AEV28LKMGifXs1SERYr+KdzkfCQyNqL0uFEEoWkbvBRcbebi4NDZu7iF52xmxXw=
-----END CERTIFICATE-----
内容を表示するには以下のようにします。
% openssl x509 -in server.crt -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 0 (0x0)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=JP, ST=Kanagawa, L=Kawasaki, O=68user's page, CN=X68000.q-e-d.net
        Validity
            Not Before: Mar 19 18:27:33 2005 GMT
            Not After : Mar 19 18:27:33 2006 GMT
        Subject: C=JP, ST=Kanagawa, L=Kawasaki, O=68user's page, CN=X68000.q-e-d.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:b6:df:76:c3:1f:b1:8d:02:04:4b:2a:fe:f1:81:
                    cc:74:e6:29:f4:6a:82:68:eb:49:c9:12:4a:e4:4a:
                    b4:fa:7d:76:80:ec:29:01:56:db:f8:ba:90:d1:e9:
                    b7:fb:ce:14:11:70:1e:2b:55:34:f8:f3:d1:c1:a0:
                    38:da:97:bc:c6:29:1c:a0:54:c6:73:21:53:90:6c:
                    6a:0d:20:a7:9f:de:61:64:ed:a2:66:93:bf:be:0a:
                    cd:d8:de:cf:9c:23:51:ed:a1:5d:d0:ab:ec:a7:b9:
                    f2:64:24:84:d7:78:40:4e:07:9c:78:ce:68:b3:77:
                    09:58:77:b7:f4:d2:7a:11:cd
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha1WithRSAEncryption
        39:80:f1:cc:f7:0c:8f:78:b4:30:59:e5:d0:1b:74:8e:94:d4:
        70:f7:9f:67:fc:f1:8c:38:16:e4:4f:bc:5b:7a:32:f1:70:da:
        46:1b:18:c9:84:68:16:9b:31:1d:78:b8:72:e3:c9:38:02:fc:
        f8:f4:f6:cf:99:ba:be:e6:00:15:b8:1c:b8:b9:ed:e5:0b:a6:
        68:03:88:bd:83:3b:e7:b7:4e:00:45:76:f0:b2:8c:1a:27:d7:
        b3:54:84:45:8a:fe:29:dc:e4:7c:24:32:36:a2:f4:b8:51:04:
        a1:69:1b:bc:14:5c:6d:e6:e2:e0:d0:d9:bb:b8:85:e7:6c:66:
        c5:7c
各項目の説明は以下のとおりです。
  • Subject: 証明される者の情報。
  • Isuuer: 証明書発行者 (認証局)。本来は Verigisn などの認証局の名前が入るべきだが、 ここでは自己署名をしたので Subject と同じになっている。
  • Validity: 証明書の有効期間。2005/3/19 18:27:33 から 1年間有効になっている (-days 365 としたから)。
  • Subject Public Key Info の RSA Public Key には Modulus と Exponent (n と e) が含まれている。

まとめ

もう一度全体の流れをおさらいします。
  1. サーバ管理者が RSA 秘密鍵 (server.key) を生成します。
  2. サーバ管理者が RSA 秘密鍵を元に CSR (Certificate Signing Request: 証明書要求。csr.pem) ファイルを生成し、認証局に送付します。
  3. 認証局が受け取った CSR を元にサーバ証明書 (server.crt) を生成し、サーバ管理者に送付します。
  4. サーバ管理者は受け取ったサーバ証明書を Web サーバに組み込みます。
ポイントをまとめます。
  • 秘密鍵 server.key と、CSR である csr.pem はサーバ管理者が生成します。
  • サーバ管理者は csr.pem を認証局に送ります。server.key は誰にも公開してはいけません。認証局に公開してもダメです。
  • 認証局は受け取った csr.pem を元に署名を行い、証明書 server.crt を生成して、サーバ管理者に送付します。
  • 最終的にサーバ管理者が必要なのは、秘密鍵 server.key と証明書 server.crt です。 いったん証明書が作成されたら csr.pem は不要になります。削除しても構いません。
  • それぞれのファイル名は何でもよいです。server-private-key.pem や server-certificate.pem としても別に構いません。 ファイルの 1行目が「BEGIN RSA PRIVATE KEY」なら RSA 秘密鍵、「BEGIN CERTIFICATE REQUEST」なら CSR、「BEGIN CERTIFICATE」なら証明書、と考えるとよいでしょう。
あとは秘密鍵 server.key と証明書 server.crt を Web サーバに組み込むだけですが、 これは次節で。
前へ << 暗号化のお話 (5) SSL/TLS の導入 (2) >> 次へ

ご意見・ご指摘は Twitter: @68user までお願いします。