私が愛した openssl (SSL/TLS 編)

id:blooper:20120907 の続きですが、皆様におかれましては既に証明書が好きで好きでたまらなくなって、HTTPS を利用したサイトに行くと証明書の拡張まで読んだ後でなくては証明書の内容が気になってサイトの本文が読めなくなっているかと思いますが如何お過ごしでしょうか。

SSL は Secure Sockets Layer の頭文字で Netscape Communications が 1995 年に、ってのは wikipedia:Secure_Sockets_Layer でも見れば載ってるので見てね。で、RFC にしようってことで SSLNetscape のでしょ? ってことで TLS (Transport Layer Security) に改名した、と記憶してるんだけど本当だっけな。ハンドシェイク時のレコードのバージョン見ると SSLv3.0 は 3.0 TLSv1.0 は 3.1 ってちょー名前だけ変わってる感じです。でも実際にはセキュリティーのこと考えて改善が行われてたりします。

何と SSL/TLS に関しても素敵なスライドがあるので置いときますね #mailerstudy 02 メールと暗号 - SSL/TLS -。一方、本で SSL/TLS つったらこれ一択ですね

(2017 年現在、「プロフェッショナル SSL/TLS」という本が出てるので、合わせて読むと TLS に関しては完璧です)

SSL/TLS は何をしたいかっつーと

  • サーバ証明書によるサーバの認証 (誰が運用してるサーバか確認)
  • 通信内容の暗号化による通信の秘匿化 (盗聴されても内容がバレない)
  • MAC を用いて通信の完全性保持 (ラブレターが改竄されると大変です)

を行って安心してインターネット使えるようにしようぜ、ってことです。公開鍵暗号は処理が重いんで、鍵交換してあとは共通鍵でやろうっつー話っすな。もちろん SSL/TLS だけで問題は閉じてなくて例えばサーバの認証には DNS による名前解決も関ってきますし、正当な証明書を持っているからといってその人達が詐欺グループかどうかの判断はまた別です。でも、最低限技術でこれだけは確保できるぜっていうラインが定まってると考えればいいのかな。

SSL/TLS はハンドシェイクしてその後に暗号化通信を行います。ハンドシェイクで行うのは

  • クライアントの使える暗号スイートの提示
  • サーバの証明書とサーバが選択した暗号スイートの提示
  • サーバが望むのであればクライアントからも証明書を提示
  • クライアントサーバ間の秘密の共有 (暗号化・MAC に使う鍵の共有)

で、これが終わると

  • 暗号化通信を開始

できます。これで終わりではなく途中で再ネゴシエーションをして定期的に鍵を更新したりもします。

ciphers

OpenSSL が使える暗号スイート (認証・鍵交換・暗号化・MACアルゴリズムの一式) の一覧を表示したり、そのうち条件を満たすものをリストアップするコマンドです。

$ openssl ciphers
ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:PSK-3DES-EDE-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:PSK-AES128-CBC-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:PSK-RC4-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5

見辛い。-v を付けると verbose です。もっと強い -V もあります。

$ openssl ciphers -v | sort | head
AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
CAMELLIA128-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(128) Mac=SHA1
CAMELLIA256-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(256) Mac=SHA1
DES-CBC-SHA             SSLv3 Kx=RSA      Au=RSA  Enc=DES(56)   Mac=SHA1
DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
DHE-DSS-AES128-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(128)  Mac=SHA1
DHE-DSS-AES256-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(256)  Mac=SHA1
DHE-DSS-CAMELLIA128-SHA SSLv3 Kx=DH       Au=DSS  Enc=Camellia(128) Mac=SHA1
DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH       Au=DSS  Enc=Camellia(256) Mac=SHA1

左から

  • 暗号スイートの名前
  • プロトコルのバージョン
  • 鍵交換の方法
  • サーバ認証の方法
  • 暗号化の方法
  • HMAC のハッシュアルゴリズム

例えば MD5 を使ってるものだけ抜きだしたかったら

$ openssl ciphers -v MD5
ADH-RC4-MD5             SSLv3 Kx=DH       Au=None Enc=RC4(128)  Mac=MD5 
RC4-MD5                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
EXP-RC2-CBC-MD5         SSLv3 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
EXP-ADH-RC4-MD5         SSLv3 Kx=DH(512)  Au=None Enc=RC4(40)   Mac=MD5  export
EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
NULL-MD5                SSLv3 Kx=RSA      Au=RSA  Enc=None      Mac=MD5 

といった感じで出てきます。MD5 のような指定するための文字列が沢山定義されているので man ciphers しましょう。

eNULL
通信の暗号をしないもの (そういうのもあるのか!)
aNULL
認証をしないもの (そういうのもあるのか!)
ALL
eNULL を使ってない全て
DEFAULT
ALL:!aNULL:!eNULL、つまり ALL から aNULL と eNULL を除いたもの。ALL の時点で eNULL は除かれてる気がする
MD5
MD5 を使ってるもの
3DES
Triple DES すな
TLSv1,SSLv3,SSLv2
そのままなんだけど、どうやらこのバージョンでは SSLv2 は一切無くなってて TLSv1 = SSLv3 みたい
EXP
米国の輸出規制にひっかかってなかったやつ、で 40bit と 56bit のが入ってるはずなんだけど 40bit しか出てこない
LOW
56bit とか 60bit のらしい
HIGH
暗号に 128bit 以上の鍵を使うものほぼ全て

なんで、

$ openssl ciphers -v 'ALL:!aNULL:!SSLv2:!LOW:!EXP:!MD5' | sort
AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
CAMELLIA128-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(128) Mac=SHA1
CAMELLIA256-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(256) Mac=SHA1
DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
DHE-DSS-AES128-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(128)  Mac=SHA1
DHE-DSS-AES256-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(256)  Mac=SHA1
DHE-DSS-CAMELLIA128-SHA SSLv3 Kx=DH       Au=DSS  Enc=Camellia(128) Mac=SHA1
DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH       Au=DSS  Enc=Camellia(256) Mac=SHA1
DHE-DSS-SEED-SHA        SSLv3 Kx=DH       Au=DSS  Enc=SEED(128) Mac=SHA1
DHE-RSA-AES128-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA1
DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(128) Mac=SHA1
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA1
DHE-RSA-SEED-SHA        SSLv3 Kx=DH       Au=RSA  Enc=SEED(128) Mac=SHA1
ECDH-ECDSA-AES128-SHA   SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128)  Mac=SHA1
ECDH-ECDSA-AES256-SHA   SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256)  Mac=SHA1
ECDH-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=3DES(168) Mac=SHA1
ECDH-ECDSA-RC4-SHA      SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=RC4(128)  Mac=SHA1
ECDH-RSA-AES128-SHA     SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128)  Mac=SHA1
ECDH-RSA-AES256-SHA     SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256)  Mac=SHA1
ECDH-RSA-DES-CBC3-SHA   SSLv3 Kx=ECDH/RSA Au=ECDH Enc=3DES(168) Mac=SHA1
ECDH-RSA-RC4-SHA        SSLv3 Kx=ECDH/RSA Au=ECDH Enc=RC4(128)  Mac=SHA1
ECDHE-ECDSA-AES128-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA1
ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH     Au=ECDSA Enc=3DES(168) Mac=SHA1
ECDHE-ECDSA-RC4-SHA     SSLv3 Kx=ECDH     Au=ECDSA Enc=RC4(128)  Mac=SHA1
ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-RSA-DES-CBC3-SHA  SSLv3 Kx=ECDH     Au=RSA  Enc=3DES(168) Mac=SHA1
ECDHE-RSA-RC4-SHA       SSLv3 Kx=ECDH     Au=RSA  Enc=RC4(128)  Mac=SHA1
EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
PSK-3DES-EDE-CBC-SHA    SSLv3 Kx=PSK      Au=PSK  Enc=3DES(168) Mac=SHA1
PSK-AES128-CBC-SHA      SSLv3 Kx=PSK      Au=PSK  Enc=AES(128)  Mac=SHA1
PSK-AES256-CBC-SHA      SSLv3 Kx=PSK      Au=PSK  Enc=AES(256)  Mac=SHA1
PSK-RC4-SHA             SSLv3 Kx=PSK      Au=PSK  Enc=RC4(128)  Mac=SHA1
RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
SEED-SHA                SSLv3 Kx=RSA      Au=RSA  Enc=SEED(128) Mac=SHA1

とりあえずこんなもんを設定しとくといいんではないかと。上から好みのものを出すのでもいいですかね。Web だったら

$ openssl ciphers -v 'aRSA+kRSA+AES:aRSA+kRSA+RC4:!EXP:!LOW:!SSLv2:!MD5'
AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1

これでこと足りる気がする。

で、この暗号スイートを指定する記法は Apache の mod_ssl の設定である SSLCihperSuite や nginx の HttpSslModule の ssl_cihpers の指定などで利用できます。脆弱性など発見された場合にはここでもってサーバの利用する暗号スイートがコントロールできます。

脆弱性とか言われると「そもそも何を使っていいわけ?」って思うわけですが、米国だと NISTSP 800-57 シリーズや SP 800-131 A 等を出したりアップデートしたりしてまして、2010 年までで新しい基準に移行のはずだったのがグダグダしてます。気が滅入ります。ただ、これは米国政府が調達する暗号に関する基準を定めてるらしくて、企業はこれに従わないと国に使ってもらえなくなるんで困っちゃいます。日本だと CRYPTOREC という

総務省及び経済産業省が共同で運営する暗号技術検討会(座長:今井秀樹中央大学教授)と、独立行政法人情報通信研究機構NICT)及び独立行政法人情報処理推進機構IPA)が共同で運営する暗号方式委員会(委員長:今井秀樹中央大学教授)、暗号実装委員会(委員長:本間尚文東北大学准教授)及び、暗号運用委員会(委員長:松本勉横浜国立大学教授)で構成され

た組織がありまして、ここで「電子政府推奨暗号のリスト」の新しいのを作ってます。2013 年に向けていま作ってます!!

暗号の移行に関する問題に関しては NTT の神田さんの暗号世代交代の現状と課題などご覧頂くのが宜しいのではないでしょうか。

s_client

SSL/TLS のクライアントとして動くコマンドです。TCP でいうところの telnet のような存在です。

$ openssl s_client -connect www.google.com:443 | cat -n
depth=1 C = ZA, O = Thawte Consulting (Pty) Ltd., CN = Thawte SGC CA
verify error:num=20:unable to get local issuer certificate
verify return:0
     1	CONNECTED(00000003)
     2	---
     3	Certificate chain
     4	 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
     5	   i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
     6	 1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
     7	   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
     8	---
     9	Server certificate
    10	-----BEGIN CERTIFICATE-----
    11	MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM
    12	MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
    13	THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x
    14	MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
    15	MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
    16	FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
    17	gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy
    18	wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B
    19	d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM
    20	BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
    21	LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
    22	BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
    23	Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
    24	ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
    25	AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp
    26	ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le
    27	IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
    28	-----END CERTIFICATE-----
    29	subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
    30	issuer=/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
    31	---
    32	No client certificate CA names sent
    33	---
    34	SSL handshake has read 2004 bytes and written 285 bytes
    35	---
    36	New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
    37	Server public key is 1024 bit
    38	Secure Renegotiation IS supported
    39	Compression: NONE
    40	Expansion: NONE
    41	SSL-Session:
    42	    Protocol  : SSLv3
    43	    Cipher    : ECDHE-RSA-RC4-SHA
    44	    Session-ID: CC221747886F54CB2870AF96F0906EF296B0D7BCB6C36614A5FAFF635AC41780
    45	    Session-ID-ctx: 
    46	    Master-Key: 5E76B3FCD73D76CCC31BAB88223A39BDC70C79854566361500CFCF385E6DC35FB024F91D0ACAE04F30FD5018D7EC61D8
    47	    Key-Arg   : None
    48	    PSK identity: None
    49	    PSK identity hint: None
    50	    Start Time: 1347280918
    51	    Timeout   : 7200 (sec)
    52	    Verify return code: 20 (unable to get local issuer certificate)
    53	---
GET / HTTP/1.0

    54	HTTP/1.0 302 Found
    55	Location: https://www.google.co.jp/
    56	Cache-Control: private
    57	Content-Type: text/html; charset=UTF-8
    58	Set-Cookie: PREF=ID=789a8a2b9473cda5:FF=0:TM=1347280923:LM=1347280923:S=3jI2H13mfEtzKGUN; expires=Wed, 10-Sep-2014 12:42:03 GMT; path=/; domain=.google.com
    59	Set-Cookie: NID=63=TRKLDcN0PL3dCcIzxMliiQq885SUmezr36BcTA8TR8mIDuyyqAiNu49bqFpjErkT74c9VIfRoLRzbB0RzROJm_7Ee9MvvH-vYYmVd2Y2NGqC5-tOaZu4pTCR13n6mRyX; expires=Tue, 12-Mar-2013 12:42:03 GMT; path=/; domain=.google.com; HttpOnly
    60	P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
    61	Date: Mon, 10 Sep 2012 12:42:03 GMT
    62	Server: gws
    63	Content-Length: 222
    64	X-XSS-Protection: 1; mode=block
    65	X-Frame-Options: SAMEORIGIN
    66	
    67	<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
    68	<TITLE>302 Moved</TITLE></HEAD><BODY>
    69	<H1>302 Moved</H1>
    70	The document has moved
    71	<A HREF="https://www.google.co.jp/">here</A>.
    72	</BODY></HTML>
read:errno=0

繋いで "GET / HTTP/1.0\n\n" 投げて返答が返ってきています。最初の部分で手元に証明書ストアがなくてサーバ証明書の認証に失敗している旨出ています。その後証明書を表示して、ハンドシェイクの結果など出してクライアントからの入力待ちでブロックします。さっきの GET 文を投げてあげるとリダイレクトの 302 レスポンスが返ってきて終了です。

上の例だと証明書ストアが無く

    52	    Verify return code: 20 (unable to get local issuer certificate)

と返して認証を諦めていました。証明書を認証したい場合、例えば Ubuntu だと /etc/ssl/certs に証明書が沢山入っているのでこれを使います (詳しくは次回の verify を見てね)

$ openssl s_client -connect www.google.com:443 -CApath /etc/ssl/certs | cat -n
depth=2 C = US, O = "VeriSign, Inc.", OU = Class 3 Public Primary Certification Authority
verify return:1
depth=1 C = ZA, O = Thawte Consulting (Pty) Ltd., CN = Thawte SGC CA
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
verify return:1
     1	CONNECTED(00000003)
(snip)
    52     Verify return code: 0 (ok)
(snip)

ストアに VeriSign の証明書があるので検証に成功して "0 (ok)" が返ってきています、てへぺろ。openssl verify の man を見れば沢山ある return code の意味が出てきます。

depth が 0 とか 1 とか 2 とか出ていますが、サーバが渡してくる証明書を全て見たい場合には -showcerts というオプションがあります

$ openssl s_client -connect www.google.com:443 -showcerts | cat -n
(snip)
     3	Certificate chain
     4	 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
     5	   i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
     6	-----BEGIN CERTIFICATE-----
     7	MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM
     8	MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
     9	THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x
    10	MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
    11	MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
    12	FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
    13	gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy
    14	wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B
    15	d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM
    16	BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
    17	LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
    18	BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
    19	Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
    20	ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
    21	AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp
    22	ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le
    23	IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
    24	-----END CERTIFICATE-----
    25	 1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
    26	   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
    27	-----BEGIN CERTIFICATE-----
    28	MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
    29	UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
    30	bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
    31	MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
    32	d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
    33	QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
    34	PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
    35	5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
    36	3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
    37	A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
    38	BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
    39	L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
    40	AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
    41	BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
    42	BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
    43	q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
    44	bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
    45	-----END CERTIFICATE-----
    46	---
    47	Server certificate
    48	subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
    49	issuer=/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
    50	---
(snip)

この場合、サーバ証明書と中間証明書の合計 2 枚の証明書を送ってきていました。

暗号スイートのリストも指定できます。例えば MD5 ばっかり送ってみると

$ openssl s_client -connect www.google.com:443 -cipher `openssl ciphers MD5`| cat -n
(snip)
    36	New, TLSv1/SSLv3, Cipher is RC4-MD5
    37	Server public key is 1024 bit
    38	Secure Renegotiation IS supported
    39	Compression: NONE
    40	Expansion: NONE
    41	SSL-Session:
    42	    Protocol  : SSLv3
    43	    Cipher    : RC4-MD5
(snip)

まだまだ MD5 を選ばせてくれました!! もっとガチガチな方向で

$ openssl s_client -connect www.google.com:443 -cipher `openssl ciphers 'aRSA+kRSA+AES:aRSA+kRSA+RC4:!EXP:!LOW:!SSLv2:!MD5'`| cat -n
(snip)
    36	New, TLSv1/SSLv3, Cipher is RC4-SHA
    37	Server public key is 1024 bit
    38	Secure Renegotiation IS supported
    39	Compression: NONE
    40	Expansion: NONE
    41	SSL-Session:
    42	    Protocol  : SSLv3
    43	    Cipher    : RC4-SHA
(snip)

RC4 大人気です。

プロトコル自体も選べて -ssl3 とか -tls1 とか -no_ssl2 とか -no_ssl3 とかあります。

$ openssl s_client -connect www.google.com:443 -tls1| cat -n
(snip)
    42     Protocol  : TLSv1
(snip)
    50     TLS session ticket lifetime hint: 100800 (seconds)
    51     TLS session ticket:
    52     0000 - bc 35 55 03 9e af e6 d8-9e ec ac 8a 6c 71 b9 3e   .5U.........lq.>
    53     0010 - e8 e6 bd cc 17 f6 d9 4a-bd 6d 13 e8 a3 ff bf a8   .......J.m......
    54     0020 - f6 c9 da 5d a7 81 b4 b9-f7 ba c1 fe f0 fb 19 8b   ...]............
    55     0030 - 9d 10 e2 eb 86 40 e2 fb-42 59 f3 e5 76 cb 73 bb   .....@..BY..v.s.
    56     0040 - a5 81 fb b1 44 94 46 21-de 15 ab 83 80 29 ad 3f   ....D.F!.....).?
    57     0050 - d6 0a 74 0f 12 ed d8 05-67 a6 ff 52 fa cd 1f a8   ..t.....g..R....
    58     0060 - d8 7a ab 28 ab a2 cf 10-e1 2e 44 07 cb 9d d4 2d   .z.(......D....-
    59     0070 - 1c df 7b 0e 78 ac e0 a9-f2 ea 17 3e 33 a1 e0 ec   ..{.x......>3...
    60     0080 - a6 cd 05 0e f1 4c 8e 33-b2 33 98 9c f9 e4 95 b9   .....L.3.3......
    61     0090 - 0b f2 10 29                                       ...)
(snip)

ticket ですって。TLSv1 にするとちょっと情報増えてますね。

他にも

  • 改行を CRLF にしてくれる -crlf オプション
  • hexdump を見せてくれる -debug オプション
  • ハンドシェイクの情報など見せずに済ませる -quiet オプション
  • 使ったことないけど SMTPIMAP などで途中から TLS に version up する -starttls オプション

など素敵オプション満載です。STMP サーバと話すときなどは -quiet -crlf 付けると万全です。

あと、証明書だけ欲しいときはよく

$ openssl s_client -connect www.google.com:443 -showcerts < /dev/null

と /dev/null を標準入力に入れたりしています。

s_server

もちろんサーバにだってなります!

$ openssl s_server -cert my.crt -key my.key
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT

ここでブロックして待ちます。netstat -tlnp してみると 4433 port を Listen してるようなので、別コンソールから

$ openssl s_client -connect localhost:4433 -quiet
depth=0 C = JP, ST = Tokyo, L = Meguro-ku, O = Samma Inc, OU = Tonosama Div., CN = meguro-ni-kagiru
verify error:num=18:self signed certificate
verify return:1
depth=0 C = JP, ST = Tokyo, L = Meguro-ku, O = Samma Inc, OU = Tonosama Div., CN = meguro-ni-kagiru
verify return:1
GET / HTTP/1.0

するとサーバの方は

-----BEGIN SSL SESSION PARAMETERS-----
MHoCAQECAgMABALAFAQgfkZyWSi46rbHl23zfvfk4W8V4nwZU31cJOoMLixkPKEE
MC4X7xGCk+5lnqpIYU3djGkbI2iD1QhvSG0e2VBLi9pMihDmgHmQiYUceVsNhpxK
qqEGAgRQTer1ogQCAhwgpAYEBAEAAACrAwQBAQ==
-----END SSL SESSION PARAMETERS-----
Shared ciphers:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5
CIPHER is ECDHE-RSA-AES256-SHA
Secure Renegotiation IS supported
GET / HTTP/1.0

まぁでも、当然 HTTPS サーバではないので何の出力もされません。ほんととりあえず繋いでるって感じのようです。

と思ったっしょ、実は

  • -www
  • -WWW
  • -HTTP

というオプションがあります。きもい! -www を足した場合には HTTPS サーバとしてサーバのパラメタを返します

(snip)
GET / HTTP/1.0
HTTP/1.0 200 ok
Content-type: text/html

<HTML><BODY BGCOLOR="#ffffff">
<pre>

s_server -cert my.crt -key my.key -www -cipher AES128-SHA 
Ciphers supported in s_server binary
TLSv1/SSLv3:AES128-SHA               
---
Ciphers common between both SSL end points:
ECDHE-RSA-AES256-SHA       ECDHE-ECDSA-AES256-SHA     DHE-RSA-AES256-SHA        
DHE-DSS-AES256-SHA         DHE-RSA-CAMELLIA256-SHA    DHE-DSS-CAMELLIA256-SHA   
ECDH-RSA-AES256-SHA        ECDH-ECDSA-AES256-SHA      AES256-SHA                
CAMELLIA256-SHA            ECDHE-RSA-DES-CBC3-SHA     ECDHE-ECDSA-DES-CBC3-SHA  
EDH-RSA-DES-CBC3-SHA       EDH-DSS-DES-CBC3-SHA       ECDH-RSA-DES-CBC3-SHA     
ECDH-ECDSA-DES-CBC3-SHA    DES-CBC3-SHA               ECDHE-RSA-AES128-SHA      
ECDHE-ECDSA-AES128-SHA     DHE-RSA-AES128-SHA         DHE-DSS-AES128-SHA        
DHE-RSA-SEED-SHA           DHE-DSS-SEED-SHA           DHE-RSA-CAMELLIA128-SHA   
DHE-DSS-CAMELLIA128-SHA    ECDH-RSA-AES128-SHA        ECDH-ECDSA-AES128-SHA     
AES128-SHA                 SEED-SHA                   CAMELLIA128-SHA           
ECDHE-RSA-RC4-SHA          ECDHE-ECDSA-RC4-SHA        ECDH-RSA-RC4-SHA          
ECDH-ECDSA-RC4-SHA         RC4-SHA                    RC4-MD5                   
EDH-RSA-DES-CBC-SHA        EDH-DSS-DES-CBC-SHA        DES-CBC-SHA               
EXP-EDH-RSA-DES-CBC-SHA    EXP-EDH-DSS-DES-CBC-SHA    EXP-DES-CBC-SHA           
EXP-RC2-CBC-MD5            EXP-RC4-MD5
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
SSL-Session:
    Protocol  : SSLv3
    Cipher    : AES128-SHA
    Session-ID: C814CE69A8BD042DF2BBFBF91625407CC34F92931ACEE1A6771CE8A9B645CE0B
    Session-ID-ctx: 01000000
    Master-Key: 196B52130E66609430DDFFCB8B116166C4906C372C7106F9CE146FFA1F516BA2FEEA7CD52D3D5EAA50AF1B9AC2E2689B
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    Compression: 1 (zlib compression)
    Start Time: 1347284148
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
   1 items in the session cache
   0 client connects (SSL_connect())
   0 client renegotiates (SSL_connect())
   0 client connects that finished
   1 server accepts (SSL_accept())
   0 server renegotiates (SSL_accept())
   1 server accepts that finished
   0 session cache hits
   0 session cache misses
   0 session cache timeouts
   0 callback cache hits
   0 cache full overflows (128 allowed)
---
no client certificate available
</BODY></HTML>
(snip)

一方 -WWW だと HTTPS サーバをエミュレートしてくれます。コマンドを走らせたディレクトリをルートとしてコンテンツを配信するだけの簡単な HTTPS サーバになります。

$ curl -s -k https://localhost:4433/Makefile | head
### Generated automatically from Makefile.org by Configure.

##
## Makefile for OpenSSL
##

VERSION=1.0.1c
MAJOR=1
MINOR=0.1
SHLIB_VERSION_NUMBER=1.0.0

s_client と同様に

  • -crlf
  • -cipher
  • -quiet
  • -tls1

などオプションがあるのでデバッグには使えるのかなぁ。

man を見ると "CONNECTED COMMANDS" ってところに Server に対して送れるコマンドが書いてあって、Q で終わったりとか r で renegotiation だとか色々楽しそうなので是非試してみてね!!