LoginSignup
5
6

More than 5 years have passed since last update.

PKI の基本と SSL証明書と OpenSSL コマンド

Last updated at Posted at 2017-01-07

PKI の基本と SSL証明書と OpenSSL コマンド

目的

  • 自分の備忘録
  • しらべごとのまとめ

対象

  • SSL証明書、なんとなく使ってるけど実はよく分かってない
    • ググった先のコマンドコピペで自己証明書作ったりはできる、けど
    • 手順が書いてあればファイルを配置してコンフィグ編集してSSL化はできる、けど

内容

  • 1. PKI とはなにか?
  • 2. SSL証明書を準備しよう
    • 自己証明書
    • Route53 + Let's Encrypt
  • 3. テストしてみよう
    • openssl コマンドを使ってみよう(s_server, s_client)
    • SSL ハンドシェイク
    • TLS バージョンと Cipher(サイファー)強度 と 脆弱性

References

1. PKI とはなにか?

PKI とは 公開鍵認証基盤 (Public Key Infrastructure) のこと

まず、以下のドキュメントを読もう。(ありがとう新野さん)

話のキーになるのは4ページ目

つまり、

  1. 情報の送信元(サーバー)は 証明書(Cert File) と 公開鍵(Public Key) を相手(クライアント)に渡す
  2. クライアントは、受け取った 証明書(Cert File) を見て信頼できると確認できたら、もらった 公開鍵(Public Key) で暗号化して送信元へ情報を渡す
  3. 送信元は受け取ったデータと、もともと持っていた 秘密鍵(Private Key) を使って暗号化を解いて情報を参照する

(共通鍵とSSLハンドシェイクについては後述する)

自己証明書を作ったことがある人はわかると思うが、いろいろと中間ファイル含めて作成するが大事なのは、

サーバの持ち物: 秘密鍵 (Private Key)
クライアントの持ち物: 証明書 (Cert File), 公開鍵 (Public Key)

だ。そこで、

「"公開"とは書いてあるが"鍵"をそんな簡単にクライアントに渡していいの?」
「秘密鍵はサーバー側で完全に管理しなければならないのに、公開鍵はいいの?」

という疑問を抱くかもしれないが、なんの問題もない。

公開鍵を使って暗号化した情報は、秘密鍵 のみで復号化できるからだ。

2. SSL証明書を準備しよう

  • 自己証明書
  • 正規のSSL証明書(無料)

2-1. 自己証明書の作成

ref. http://qiita.com/akito1986/items/8eb41f5a43bb9421ae79

自己証明書の利用には注意
可能なら無料もあるので正規の証明書を使いたいところ

  • -subj オプションを使うことで非対話にすることが可能です。
client_side
openssl genrsa -out ca-privatekey.pem 2048

openssl req -new -key ca-privatekey.pem -out ca-csr.pem \
-subj "/C=JP/ST=Tokyo/O=Test Company/OU=IT Department/CN=ssl.example.com"

openssl req -x509 -key ca-privatekey.pem -in ca-csr.pem -out ca-crt.pem -days 3560
server_side
openssl genrsa -out server-privatekey.pem

openssl req -new -key server-privatekey.pem -out server-csr.pem \
-subj "/C=JP/ST=Tokyo/O=Test Company/OU=IT Department/CN=ssl.example.com"

openssl x509 -req -CA ca-crt.pem -CAkey ca-privatekey.pem -CAcreateserial -in server-csr.pem -out server-crt.pem -days 3650
  • Serverに置くファイル
    • server-crt.pem
    • server-privatekey.pem
  • クライアントに置くファイル
    • ca-crt.pem

2-2. 正規のSSL証明書(無料)

2017 現在、無料でSSL証明書を取得できます。有名なのな以下の2つでしょうか。

今回は AWS 以外での利用も可能なように Let's Encrypt を利用します

1) まずは ドメイン名 を取得します。.net などであれば年額1000円程度(US$11.0)で取得可能です。
2) 恒久的なグローバルIPをもったサーバーもしくは仮想マシンを準備します。
3) Let's Encrypt で証明書を作成します。
sudo yum update -y

sudo yum install epel-release
sudo yum install certbot git

sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

cd /opt/letsencrypt
sudo -H ./letsencrypt-auto certonly --standalone -d www.test-domain.net

sudo ls -al /etc/letsencrypt/live/www.test-domain.net/fullchain.pem
output
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/www.test-domain.net/fullchain.pem. Your cert
   will expire on 2017-04-07. To obtain a new or tweaked version of
   this certificate in the future, simply run letsencrypt-auto again.
   To non-interactively renew *all* of your certificates, run
   "letsencrypt-auto renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to *****@gmail.com.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
sudo ls /etc/letsencrypt/live
www.test-domain.net

sudo ls /etc/letsencrypt/live/www.test-domain.net
cert.pem  chain.pem  fullchain.pem  privkey.pem

3. 証明書をテストする

3-1. openssl コマンドを使ってみよう(s_server, s_client)

  • ref.
    • man s_client
    • man s_server
server_session
sudo openssl s_server -key \
> /etc/letsencrypt/live/www.test-domain.net/privkey.pem \
> -cert /etc/letsencrypt/live/www.test-domain.net/cert.pem \
> -accept 443 -www -state -debug
client_session
echo "Q" | openssl s_client -connect localhost:443 -state -debug
  • ブラウザからアクセスしてみましょう。

  • 以下のように緑の鍵アイコンが表示されていれば有効な証明書でHTTPS通信できています。

  • テストが終わったら openssl コマンドで実行している s_server セッションを Ctrl + c で終了させておきます。

Screenshot 2017-01-08 02.26.10.png

3-2. SSL ハンドシェイク

クライアント側の動きは上で実行した openssl s_client コマンドから確認できます。

実行例
$ sudo echo "Q" | openssl s_client -connect localhost:443 -state 2>&1 | grep SSL_
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read server session ticket A
SSL_connect:SSLv3 read finished A
  • サーバ側も同様
$ sudo openssl s_server -key \
> /etc/letsencrypt/live/www.test-domain.net/privkey.pem \
> -cert /etc/letsencrypt/live/www.test-domain.net/cert.pem \
> -accept 443 -www -state 2>&1 | grep SSL_

SSL_accept:before/accept initialization
SSL_accept:SSLv3 read client hello A
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write key exchange A
SSL_accept:SSLv3 write server done A
SSL_accept:SSLv3 flush data
SSL_accept:SSLv3 read client key exchange A
SSL_accept:SSLv3 read finished A
SSL_accept:SSLv3 write session ticket A
SSL_accept:SSLv3 write change cipher spec A
SSL_accept:SSLv3 write finished A
SSL_accept:SSLv3 flush data

3-3. TLS バージョンと Cipher(サイファー)強度 と 脆弱性

  • TL;DR 端的に言うと、そのときに利用可能な最新の openssl バージョンを利用することで強度の高い Cipher Suite(暗号アルゴリズムの組み合わせ)を利用することができ、 すくなくとも利用開始時点でより安全な SSL/TLS 環境を構築することができる、ということ。

  • openssl のバージョン確認

  • リリース

  • サーバ上

$ openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013

$ rpm -q openssl
openssl-1.0.1e-60.el7.x86_64
  • 利用可能な Cipher Suite

ref. man ciphers

実行例
$ openssl ciphers -v ECDH+aRSA+HIGH
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
ECDHE-RSA-DES-CBC3-SHA  SSLv3 Kx=ECDH     Au=RSA  Enc=3DES(168) Mac=SHA1
  • どの Cipher Suite を使うべきかは IPA のガイドラインを参照して参考にしても良いと思います。
  • 例えばクライアント側の環境が古いなどでサーバ側の暗号化強度を高い方で制限しにくい場合などもあり、弱めから強いのまで幅広く対応せざるを得ないこともあります。

おまけ

所感: 端的に言うとサーバーサイドのキャッシュ保持が不要になるため、分散環境などで有効かもしれません。あと、キャッシュサイズの増加の心配もなくなりそうなので適切な利用が進むと良いのではないかと思います。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6