私が愛した openssl (PKI 編 その 2)

id:blooper:20120907 の続きです。参考図書などはそっちを見て頂くのが宜しいのではないかと。

pkcs12

PKCS#12 形式のファイルを扱います。PKCS に関しては wikipedia:PKCS を、でした。昔は PFX と言っていたらしく、Windows だと今でも拡張子を .pfx としています。.p12 は、いけるんだっけ? 何の為の形式かっつーと、証明書とそのペアの秘密鍵を格納して、秘密鍵パスフレーズで暗号化します。その他認証局の証明書も格納できます。例えば、Windows の CryptoAPI とか Java の keytool とか IBM の iKeyman とかは、RSA 秘密鍵をそのままではインポートできなくて、PKCS#12 形式にして証明書と一緒にインポートしてあげる必要があります、たしか。

先ずは作ってみます

$ openssl req -new -x509 -newkey rsa:2048 -keyout abc.key -out abc.crt
$ openssl pkcs12 -export -inkey abc.key -in abc.crt -out abc.p12
Enter pass phrase for abc.key:
Enter Export Password:
Verifying - Enter Export Password:

自己署名証明書を RSA2048 で作って鍵を abc.key 証明書を abc.crt に保存したあと、その 2 つのファイルを abc.p12 としてまとめました。

$ openssl pkcs12 -export -inkey abc.key -in abc.crt -out abc.p12 -certfile google.crt
||
と -certfile を指定すると中間証明書なども格納できます、が、全く検証せずにとりあえずつっこむみたいです。www.google.com から取ってきた証明書つっこんでどうするんだっつー。

で、中身を見るには、
>|sh|
$ openssl pkcs12 -in abc.p12 -nodes | grep BEGIN
Enter Import Password:
MAC verified OK
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-----BEGIN PRIVATE KEY-----

ふお、MAC を検証してる。MAC で完全性を確保してるんですね、知らなかった! -nodes で出力される秘密鍵パスフレーズをつけないでいます。これで abc.crt, google.crt, abc.key が abc.p12 から抜き出せています。

$ openssl pkcs12 help
(snip)
-nocerts      don't output certificates.
-clcerts      only output client certificates.
-cacerts      only output CA certificates.
-nokeys       don't output private keys.

などでエンド証明書だけとか認証局証明書だけとか、鍵を出す出さないとか、コントロールできます。

verify

あぁ、検証。証明書を検証します。その証明書が正当なものかどうかを検証するわけですが、正当って何でしょうねぇ。

正解は RFC 5280 などで理解しなくてはいけませんが、最低限

  • 有効期間内のものかどうか
  • 信用している (自己署名) 証明書まで署名のチェインを辿れるか
  • 失効されていないか
  • 証明書ポリシーなど認証局の定めた制限をパスしているか

など確認しなくてはいけません。この最後の奴が何とも面倒臭そうです。というか特に最後の部分は検証するときの解釈もあるので解釈を定めてからでないと検証の結果も一意には定まりません。なので面倒なのでちょっと放置。

とりあえず、証明書を取ってきましょう。

$ openssl s_client -connect www.google.com:443 -showcerts < /dev/null
(snip)
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
   i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
-----BEGIN CERTIFICATE-----
MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x
MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy
wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B
d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM
BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp
ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le
IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
-----END CERTIFICATE-----
 1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
-----BEGIN CERTIFICATE-----
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
-----END CERTIFICATE-----
(snip)

2 枚出てきたのでそれぞれ server.crt と intermediate.crt として保存します。

早速 verify

$ openssl verify server.crt 
server.crt: C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
error 20 at 0 depth lookup:unable to get local issuer certificate

失敗してしまいました。認証局の証明書を信頼する証明書として指定してやらなくてはいけません。

$ openssl verify -CAfile intermediate.crt server.crt
server.crt: OK

成功しました。でもでも、CRL とかもチェックしてみたいものです。

$ openssl x509 -noout -text < server.crt | egrep -i crl
            X509v3 CRL Distribution Points: 
                  URI:http://crl.thawte.com/ThawteSGCCA.crl
$ curl http://crl.thawte.com/ThawteSGCCA.crl | openssl crl -inform der >> intermediate.crt 

server.crt の中身から CRL にマッチする行を探したら http://crl.thawte.com/ThawteSGCCA.crl にあることが分かったので、curl で取ってきて openssl crl で受けて DER から PEM にして intermediate.crl に追記しました。

$ openssl verify -crl_check -CAfile intermediate.crt server.crt
server.crt: OK

成功しました。あと、例えば証明書の用途も確認できます。

$ openssl verify -CAfile intermediate.crt -purpose sslserver server.crt
server.crt: OK
$ openssl verify -CAfile intermediate.crt -purpose timestampsign server.crt
server.crt: C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
error 26 at 0 depth lookup:unsupported certificate purpose
OK

OK って言っちゃうの? でも error 26 が出てますね。man verify すると

       26 X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose
           the supplied certificate cannot be used for the specified purpose.

と説明があります。他のコードも説明があります。

では、intermediate.crt は信じていいのか? intermediate.crt の Issuer は

$ openssl x509 -in intermediate.crt -noout -issuer
issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority

という証明書で、これは自己署名されているルート証明書でした。

$ openssl x509 -in intermediate.crt -noout -issuer_hash
415660c1

上の名前 (の DER エンコーディングされたもの) のハッシュを取ると 415660c1 なのですが、

$ ls -l /etc/ssl/certs/415660c1*
lrwxrwxrwx 1 root root 59 2011-12-27 01:01 /etc/ssl/certs/415660c1.0 -> Verisign_Class_3_Public_Primary_Certification_Authority.pem
$ openssl x509 -in /etc/ssl/certs/415660c1* -noout -issuer -subject
issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
subject= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority

ハッシュ値.0 という名前でシンボリックリンクが作られています。これは -CApath ファイルで指定するディレクトリに証明書を保存しておく約束で、指定されたディレクトリからハッシュ値を使って使うべき証明書を探すわけです。なので

$ openssl verify -CApath /etc/ssl/certs intermediate.crt
intermediate.crt: OK

と正しい証明書を見つけてくれて OK と出ました。

$ openssl x509 -in intermediate.crt -noout -text | egrep -i crl
                Certificate Sign, CRL Sign
            X509v3 CRL Distribution Points: 
                  URI:http://crl.verisign.com/pca3.crl
$ curl -s http://crl.verisign.com/pca3.crl | openssl crl -inform der > pca3.crl
$ openssl verify -CApath /etc/ssl/certs -CAfile pca3.crl intermediate.crt
intermediate.crt: OK

と、-CApath で信頼する証明書のリストを、-CAfile で CRL を指定するなんてこともできます。

あとは、-policy_check とかのオプションもあります。

pkcs7

PKCS#7 というのは、wikipedia:wiki/PKCS によると

PKI の下でメッセージを署名や暗号化するのに使用される。証明書の配布のためにも用いられる(例えば、PKCS #10メッセージの応答として)。

とのことですが、例えば Windows 用に複数の中間証明書を配布する為などに使われています。拡張子は p7b すかね。google:filetype:p7b Google すげぇな。

$ openssl pkcs7 -in my.p7b -print_certs

のようにすると、中に入っている証明書を取り出すことができます。

crl2pkcs7

名前に騙されてはいけなくて、man にもあるように "Create a PKCS#7 structure from a CRL and certificates." と CRL だけでなく証明書も使えます。

とりあえず CRL をつっこんでみると

$ openssl crl2pkcs7 -in ThawteSGCCA.crl -inform der |head -n 2
-----BEGIN PKCS7-----
MIIZeAYJKoZIhvcNAQcCoIIZaTCCGWUCAQExADALBgkqhkiG9w0BBwGgAKGCGUsw

確かに変換されていますし、

$ openssl crl2pkcs7 -nocrl -certfile server.crt -certfile intermediate.crt | openssl pkcs7 -noout -print_certs
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
issuer=/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA

subject=/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
issuer=/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority

と、証明書が詰まった PKCS#7 形式も作れます。上の例だと 2 枚の証明書をつっこんでいます。

ocsp

CRL はファイルなので、常時更新されているかも分からず、基本的にオフラインで利用されることが想定されていました。それじゃダメでしょ、ってことでオンラインの失効情報確認の仕組みが OCSP (Online Certificate Status Protocol) です。OCSPRFC 2560 などで定義されていて、

  • リクエストのバイナリ形式
  • レスポンスのバイナリ形式
  • リクエスト方法
  • レスポンス方法

などが定義されています。

ocsp はリクエストやレスポンスの生成、OCSP クライアント、OCSP サーバになれる何でも屋さんなのですが、失効情報など管理するにあたって沢山のファイルを利用します。ca と ocsp は仲良しさんなので、一緒に使うことを想定されてるみたいです。

サーバ機能に関しては、HTTP サーバなわけですが、貧弱すぎたり返事が上手く取ってこれなかったりで、結局 Apache か nginx に proxy させて CGI か何かで ocsp 呼んでレスポンス返してみた気がします。今はどうなんだろうな。

man ocsp の EXAMPLE 見れば分かるんですが、というともぉ自分の存在意義を否定し始めてますが

$ openssl ocsp -issuer intermediate.crt -cert server.crt -reqout req.der

で、OCSP リクエストを生成します。このリクエストをサーバに送りつけたいわけですが、

$ openssl x509 -in server.crt -noout -text | egrep -i ocsp
                OCSP - URI:http://ocsp.thawte.com

というわけで

$ openssl ocsp -issuer intermediate.crt -cert server.crt -url http://ocsp.thawte.com -resp_text -respout resp.der -CAfile intermediate.crt
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = ZA, O = Thawte Consulting (Pty) Ltd., CN = Thawte SGC OCSP Responder
    Produced At: Sep 11 18:03:43 2012 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: 1E9209AA713C794BCA1E931A0A61AD3FD0BA6083
      Issuer Key Hash: 3B349A709173B28A1B0CF4E937CDB370329E1854
      Serial Number: 4F9D96D966B0992B54C2957CB4157D4D
    Cert Status: good
    This Update: Sep 11 18:03:43 2012 GMT
    Next Update: Sep 18 18:03:43 2012 GMT

    Signature Algorithm: sha1WithRSAEncryption
        1a:73:a7:22:9a:ec:22:6a:d0:b8:28:7c:a0:01:0f:37:2a:5c:
        69:e3:2d:c1:6f:3f:98:53:1a:cd:bc:ae:de:dc:19:9b:47:bd:
        77:ef:32:13:23:ef:28:da:a1:56:bf:8b:00:f9:96:25:04:f2:
        09:c5:6e:93:ff:61:28:2d:46:65:e7:fc:d6:e0:82:c4:64:fc:
        ec:59:12:5f:02:ce:76:fa:c6:8e:00:ef:d0:a5:34:a5:26:b9:
        4c:6b:39:46:49:f9:3a:19:ad:84:f2:95:de:0d:2b:82:88:49:
        d3:18:2e:0f:97:69:36:97:3f:76:53:c3:2e:65:ce:60:81:e4:
        a0:a3
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            01:8b:4d:61:4e:17:e0:9b:95:c2:05:bc:01:24:1a:38
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=ZA, O=Thawte Consulting (Pty) Ltd., CN=Thawte SGC CA
        Validity
            Not Before: Aug 17 00:00:00 2012 GMT
            Not After : Nov 15 23:59:59 2012 GMT
        Subject: C=ZA, O=Thawte Consulting (Pty) Ltd., CN=Thawte SGC OCSP Responder
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:cf:4f:fa:fd:ba:ba:3c:05:6b:03:99:fe:3c:2f:
                    62:62:15:f6:84:89:09:f4:06:44:3c:d2:69:b1:1f:
                    11:1e:18:21:02:bb:22:cf:79:b7:e7:81:4c:1c:92:
                    76:35:64:87:ca:4b:86:5f:36:2b:9b:a0:a8:56:29:
                    08:f7:ff:a8:38:e3:73:4a:bf:f9:87:50:54:12:12:
                    9d:c4:2e:82:ad:3d:7e:21:7a:cd:68:af:9a:d2:d2:
                    04:a6:79:10:4d:dd:c7:11:01:91:f5:c1:39:f8:6c:
                    a5:14:52:19:b3:be:62:9a:4c:59:89:07:34:ce:8e:
                    5c:69:ca:9b:98:b8:0c:88:39
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Extended Key Usage: 
                OCSP Signing
            X509v3 Key Usage: 
                Digital Signature
            OCSP No Check: 

            X509v3 Subject Alternative Name: 
                DirName:/CN=OCSP8-TGV7-376
    Signature Algorithm: sha1WithRSAEncryption
        13:09:e4:dd:fa:1f:7c:e5:7b:15:d6:d6:5a:8e:43:cb:f8:c2:
        e3:b5:fc:63:42:6a:81:77:56:9b:a3:42:2c:f5:b2:b2:35:cd:
        aa:ba:30:61:f2:ee:02:e1:22:bc:37:52:05:69:c1:b9:c9:42:
        73:80:1e:ea:93:d4:99:38:8d:1e:5c:06:38:66:91:be:45:c9:
        74:3c:38:78:71:dd:3e:55:4b:32:af:60:d0:0d:c6:a3:77:05:
        d4:05:f3:b4:86:26:6f:81:9b:27:7c:71:fc:41:57:f8:9c:e6:
        1e:11:56:8c:65:fb:1b:11:73:73:f7:b5:ce:82:85:9d:6d:51:
        b7:1d
-----BEGIN CERTIFICATE-----
MIICkTCCAfqgAwIBAgIQAYtNYU4X4JuVwgW8ASQaODANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMjA4MTcwMDAwMDBaFw0x
MjExMTUyMzU5NTlaMFgxCzAJBgNVBAYTAlpBMSUwIwYDVQQKExxUaGF3dGUgQ29u
c3VsdGluZyAoUHR5KSBMdGQuMSIwIAYDVQQDExlUaGF3dGUgU0dDIE9DU1AgUmVz
cG9uZGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPT/r9uro8BWsDmf48
L2JiFfaEiQn0BkQ80mmxHxEeGCECuyLPebfngUwcknY1ZIfKS4ZfNiuboKhWKQj3
/6g443NKv/mHUFQSEp3ELoKtPX4hes1or5rS0gSmeRBN3ccRAZH1wTn4bKUUUhmz
vmKaTFmJBzTOjlxpypuYuAyIOQIDAQABo2gwZjAJBgNVHRMEAjAAMBMGA1UdJQQM
MAoGCCsGAQUFBwMJMAsGA1UdDwQEAwIHgDAPBgkrBgEFBQcwAQUEAgUAMCYGA1Ud
EQQfMB2kGzAZMRcwFQYDVQQDEw5PQ1NQOC1UR1Y3LTM3NjANBgkqhkiG9w0BAQUF
AAOBgQATCeTd+h985XsV1tZajkPL+MLjtfxjQmqBd1abo0Is9bKyNc2qujBh8u4C
4SK8N1IFacG5yUJzgB7qk9SZOI0eXAY4ZpG+Rcl0PDh4cd0+VUsyr2DQDcajdwXU
BfO0hiZvgZsnfHH8QVf4nOYeEVaMZfsbEXNz97XOgoWdbVG3HQ==
-----END CERTIFICATE-----
WARNING: no nonce in response
Response verify OK
server.crt: good
	This Update: Sep 11 18:03:43 2012 GMT
	Next Update: Sep 18 18:03:43 2012 GMT

証明書付きで結果を返してくれています。"server.crt: good"!! intermediate.crt を二回指定していますが、-CAfile で指定している方はレスポンスの署名の確認用の証明書指定だそうです。

サーバの方は面倒なので省略。サーバの方をやるなら ca を先に説明するべきだな!

ca

CA は Certification Authority の頭文字、これは認証局のことです。簡単な認証局を運用できるような便利な仕組みを用意してくれています。CA を運用するには

  • 認証局の証明書
  • 認証局秘密鍵
  • CSR への署名
    • 有効期限の設定
    • シリアルの割当
    • 証明書拡張の付与
  • 発行した証明書とそのステータスの管理
  • CRL の作成

などがあるので、これらを設定ファイルやオプションで指定して実行できるようになっています。

これも、面倒だから省略。気が向いたら更新するかもね! っていうかその気にさせてよ!!

私が愛した 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 だとか色々楽しそうなので是非試してみてね!!