SSLの基礎
SSL関連の情報。自宅LinuxでApache+mod_sslでSSLサーバを立ててセキュリティについて勉強してみる。 SSLはSecure Socket Layerの略で、WebブラウザがWebサーバと通信する時に使われるセキュリティ技術で最も一般的な物でしょう。SSLには大きく分けて以下の機能があります。- サーバ認証による通信相手の認証
- 通信路の暗号化による秘匿性の確保
- 通信データの改竄防止
サーバ認証
サーバ認証とはWebブラウザ等のクライアントがWebサーバにアクセスする際に、 本当に正当なサーバにアクセスしているかどうかを検証する仕組みです。 通常Webブラウザにはルート証明書と呼ばれる証明書がインストールされています。 この証明書を用いて、アクセス先のサーバが送ってくる証明書が正しい物かどうかを 認証するのです。これによりクライアントがフィッシングサイト等の悪意を持った サーバにアクセスする事を防ぐ事ができます。実際の仕組みは簡単に言うと、 サーバ証明書にはそのサーバのURLを含むコモンネームという部分が含まれていますので、 クライアントがアクセスを希望するURLとサーバから送られてくるURLを比較し、 合っていれば正しいサーバと見なす事になります。この時重要となるのが証明書を発行 するCAという機関になります。サーバ証明書が誰でも発行できてしまえば、 適当なサーバ証明書を作ってしまえば詐欺行為が可能になってしまうので 信頼できる第三者機関がこの発行を受け持っています。これがVerisignや Geotrust等の電子認証機関で、クライアントとサーバが同じ電子認証機関の 証明書を持って、検証する事になります。暗号化
サーバが確認できれば、後は秘密を保持する必要のあるデータをサーバと送受信する事になります。Webの世界で広く使われている HTTPはテキストのデータをやり取りするのが基本ですので、そのデータを送受信すると、銀行口座の番号や各種パスワード、その個人情報が他人に容易に見る事ができる、テキストデータとして経路を流れてしまいます。これらの情報は一般的には他人に知られたくありませんので、暗号化を行う必要があります。この暗号化のやり取りがSSLのハンドシェイク(Handshake)と呼ばれる手順に含まれます。サーバとクライアントは、まずクライアントがサポートできる暗号化アルゴリズムをサーバ側に宣言し、基本的にはその中で最強のアルゴリズムをサーバ側は選択し、鍵のやり取りを行い、データを暗号化し、他人から見る事をできなくします。改竄防止
データが暗号化されても、そのデータは本当に正規の物かは不明です。第三者がデータを傍受し意図的に改変して、クライアントに流すかもしれません。これを防ぐにはメッセージダイジェストと呼ばれるハッシュ値を使用して防ぎます。予めデータの送信側が送るデータのハッシュ値を計算し、それをクライアント側に送ります。データが改竄されるとハッシュ値が変わってきますので、受信側は受け取ったデータとハッシュ値を計算し、途中で改竄されていないかどうかを検証する事になります。SSL Related Specs
SSLには、その歴史によりSSL version2/SSL version3/TLS(Transport Layer Security)1.0と進化をしてきました。現在ではTLSが一般的に 使われているバージョンになります。SSL Version2(by Netscape)
SSL Version3(by Netscape)
TLS Version1.0(by IETF)日本語訳
TLS spec(English)
X509(証明書の仕様)
RFC3739 Internet X.509 Public Key Infrastructure: Qualified Certificates Profile
RSA PKCS (Public Key Cryptography Standard)
FireFoxのSSL関連のエラーコード一覧
OpenSSL
OpenSSLはフリーのSSL関連のツールキットで様々な機能があります。mod_sslを利用する場合にも必要に なりますのでインストールしましょう。OpenSSL英語マニュアル
証明書
証明書には大きく分けて、ルート証明書、サーバー証明書、クライアント(ユーザー)証明書があります。 クライアント証明書を使ってクライアント認証を行う場合は法人利用の場合を除いて少ないと思いますが、 サーバ証明書を使った、サーバ認証は、証券会社や銀行のアカウントを使用する時など頻繁に使うと思います。サーバ認証の大切な役割は、ユーザーがアクセス使用としているサイトが本物であるかどうかを検証する事にあります。
証明書の発行
SSLの基礎にも書きましたが、通常SSLサーバを正式に運用する時は、信頼できるVerisignやGeotrust等の 証明書発行機関に証明書発行の依頼を出さないといけません。しかし、お遊びでSSLサーバを立てるのであれば 自分がCA局になってしまい、ルート証明書を自分のPCのブラウザにインストール すれば良いので、簡単に証明書を発行できます。[root@lab apps]# ./CA.sh -newca
[root@lab apps]# ./CA.sh -newreq
[root@lab apps]# ./CA.sh -sign
証明書フォーマットの変換
一般に流通?している証明書には様々なフォーマット(DER,BER,PEM)の物があり、OpenSSLのコマンドで簡単に変換できます。DER 形式でバイナリエンコーディングされたものはX.509形式やPKCS#7形式の物がある。 X.509かPKCS#7であるかは、OpenSSLコマンドで見る事が可能。 実行例: $ openssl pkcs7 -inform der -in ファイル名 -text もしくは $ openssl x509 -inform der -in ファイル名 -text
SSLv3 通信内容のデコード方法(ssldumpの使い方)
実際にサーバを立てたら、SSLのハンドシェイク(Handshake)の内容を見てみましょう。ブラウザとWebServerの間で、鍵や 証明書のやり取りを見る事が出来ます。代表的なフリーのパケットキャプチャツールのEtherealでも暗号化される前の Handshake部分の通信内容を見る事ができますが、 Handshake終了後は暗号化されてしまい、詳しい内容は見る事ができません。 しかし、サーバ証明書の秘密鍵を持っていれば、 ssldumpというフリーのユーティリティツールを 使用して通信内容をデコードできます。但しSSLv3のみでSSLv2はできません。 (SSLv2の場合は必殺ヒューマンデコードが出来る場合がりますが、割愛します。。。) ssldumpの使い方はssldumpオフィシャルサイトにあります。 基本的にはサーバの秘密鍵と対応するパスフレーズの指定を変更する事でいろんなホストとの 通信内容をデコードできます。残りのオプション(以下のコマンドラインサンプルの赤字の部分) は変更しなくてよいと思います。以下にSSLv2とSSLv3の場合のデコードサンプルを載せておきます。
注意:ssldumpが対応していないアルゴリズムが使用された場合はデコードできません。 (ssldump自体が古く、TLSが使用される場合はデコードできません。自宅Linuxで遊ぶならサーバ側やクライアント側で強制的にTLSを使わない様に 指定して実験する必要があります。)
例 [root@lab root]# cd ./ssldump-0.9b3 [root@lab ssldump-0.9b3]# ./ssldump -Ad -i "if_name(eth0)" -k "key_file_name" -p "passphrase"
SSLv2 ssldump sample
New TCP connection#3: 192.168.1.103(1098) <-> test1-1.ne.jp(443) 3 1 0.9985 (0.9985) C>S SSLv2 compatible client hello Version 3.0 cipher suites SSL2_CK_3DES SSL2_CK_RC4 SSL2_CK_RC2 SSL2_CK_DES SSL2_CK_RC4_EXPORT40 SSL2_CK_RC2_EXPORT40 SSL_RSA_WITH_3DES_EDE_CBC_SHA SSL_RSA_WITH_RC4_128_MD5 SSL_RSA_WITH_RC4_128_SHA SSL_RSA_WITH_DES_CBC_SHA SSL_RSA_EXPORT_WITH_RC4_40_MD5 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 Unknown SSL content type 131 Unknown SSLcontent type 128 3 2 2.1023 (1.1037) S>CShort record Unknown SSL content type 0 3 3 2.1026 (0.0003) S>CShort record Unknown SSL content type0 3 4 2.1029 (0.0002) C>SShort record Unknown SSL content type 03 5 3.8059 (1.7030) S>CShort record Unknown SSL content type 1 36 3.8067 (0.0007) S>CShort record 33.8067 (0.0000) S>C TCP FIN 3 7 3.8069(0.0002) C>SShort record 3 3.8110 (0.0041)C>S TCP FIN
SSLv3 ssldump sample
クライアント認証ありの場合のサンプルです。
New TCP connection #3: 192.168.1.103(1086)
<-> test1-2.ne.jp(443) 3 1 0.9988(0.9988) C>S SSLv2 compatible client
hello Version
3.0 cipher
suites
SSL2_CK_3DES
SSL2_CK_RC4
SSL2_CK_RC2
SSL2_CK_DES
SSL2_CK_RC4_EXPORT40
SSL2_CK_RC2_EXPORT40
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_RC4_128_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_RSA_EXPORT_WITH_RC4_40_MD5
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 3 2 0.9995 (0.0007)S>CV3.0(74) Handshake
ServerHello
Version 3.0
random[32]=
50 4e c9 76 19 e8 db 89 43 86 42 b0 43 b6 20 fb
27 1d b5 f4 cb 77 ee b2 56 23 1b 26 2a 94 fd c7
session_id[32]=
46 69 53 9f 63 89 8a be b6 4a 83 80
20 bc c4 2d f4 2e 8a 07 d1 2a eb 65 0e b8 0c ca
be f6
98 4c
cipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA compressionMethod NULL 33 0.9995
(0.0000)
S>CV3.0(874) Handshake Certificate 3 40.9995 (0.0000)
S>CV3.0(229)
Handshake CertificateRequest
certificate_types rsa_sign
certificate_types
dss_sign
certificate_authority
certificate_authority ServerHelloDone 3 5 5.6060(4.6065) C>SV3.0(2372)
Handshake
Certificate 3 6 6.5071 (0.9010)C>SV3.0(132) Handshake
ClientKeyExchange
EncryptedPreMasterSecret[128]=
95 73 3e 0d 52 65 6d 57 b0 87 30 78 54 23 65
4a a9 b8 47 03 2b fc ca ab d0 19 54 15 2b 11 82
dc af ec bb 3f a8 66 97 d5 b7 28 23 6f 1d f0 ae
8b d2 61 57 20 4e 60 66 93 4e 0a 44 8c f7 9b 01
9a 3a 1c 41 38 6e f6 b5 04 5f 7a db c4 f1 4f 0e
5a 9b 54 fb 32 a8 c5 3d b4 12 1e 80 e6 80 e9 92
98 9f 96 03 c7 19 b5 ec 97 83 61 77 1d b5 56 0c
28 b0 95 20 9e 16 e1 b0 54 ca 97 05 69 e7 fe 75
0c 3 7 6.5071 (0.0000)C>SV3.0(134) Handshake
CertificateVerify
Signature[128]=
b7 b0 ab 8d 1c d8 bb 59 0e 7b 07 ea a6 cc
0e ee 33 73 95 7f b1 dc ad 9e 44 86 ce ed d3 1e
39 28 a4 fa 22 d9 e2 cd 2e 41 2a 37 12 35 ac 17
d3 f5 34 e1 a7 c8 88 da 18 29 1f 6c 8c 32 a5 d8
b0 13 69 7e de 79 bc fe 23 97 a0 b6 cf 2f 40 44
9b ed 3a 73 7a 15 3f 9b ba 51 b1 4f 4f 2e 69 5d
10 b6 e4 67 13 ba 43 b1 be 3e 5b ed ca 0b 52 6a
18 0e 9d ca 67 a3 dd 42 32 fa 3f 62 ea 54 a3 7e
23 d0 3 8 6.5071(0.0000) C>SV3.0(1)
ChangeCipherSpec 3 9 6.5071 (0.0000)C>SV3.0(64) Handshake
Finished
md5_hash[16]=
51 11 85 62 58 45 ab 62 9d f4 21 11 b2 87 b9 b3
sha_hash[20]=
fb 75 b4 76 82 d0 23 b8 80 57 e4 56 0c 1e
11 1a e0 39
74 3b 3 10 6.5223(0.0152) S>CV3.0(1)
ChangeCipherSpec 3 11 6.5223 (0.0000)S>CV3.0(64) Handshake
Finished
md5_hash[16]=
ce 8a f7 9b 5c c9 5a 1a 29 ce 53 5d 03 69 c6 51
sha_hash[20]=
37 71 45 85 98 96 d1 7b 8c 22 7d 52 3b 74
ef bc 35 14
e3 f3 3 12 7.5085(0.9861) C>SV3.0(144)
application_data
--------------------------------------------------------------- GET /SSL/ok.htm
HTTP/1.1 Host:
test1-2.ne.jp
User-Agent:
--------------------------------------------------------------- 3 13 7.5095 (0.0009)S>CV3.0(448) application_data
---------------------------------------------------------------
HTTP/1.1 200 OK
Date: Tue, 11 Sep 2012 05:17:48 GMT
Server: Apache/1.3.33 (Unix) mod_ssl/2.8.22 OpenSSL/0.9.7g
Last-Modified: Fri, 05 Jan 2007 05:15:36 GMT
ETag: "30191-92-459ddef8"
Accept-Ranges: bytes
Content-Length: 146
Connection: close
Content-Type: text/html
<HTML><BODY>
<head>
<title>index </title>
</head>
now ok <br>
<A href="http://test.ne.jp/index.htm">go main</A><br>
</BODY></HTML>