~ To be, or not to be, or to let it be. ~ null-i.net |
Linux/OpenSSL | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OpenSSL(2014-12-28) SSLについて色々できるオープンなやつ((Apacheライセンスです。フリーウェアで、わりと自由に使っていいよというもの。 まず初めに†そもそも、CAって何?公開鍵って何?という話が初耳の方はさっぱり分からないですよね。 私も書いてて初めて気づいたんですが、とにかくコマンドのオプションだけでも多い! 基本的な標準コマンド†・・・というか、今回抜粋してみたものは以下になります。
用語:拡張子について†各コマンドで使用される拡張子・ファイル形式について
dst: ダイジェスト計算†ハッシュ値の計算や、データへの署名実行、署名検証を行います。 ハッシュ値計算の例として $ cat IROHA.txt いろはにほへとちりぬるを(中略)ひもせす! $ openssl dgst -md5 IROHA.txt MD5(IROHA.txt)= 9c027e1a2a67967d26c6f4434f4086b5 $ md5sum IROHA.txt # こうやっても同じ結果になりますね。-sha1 と sha1sum も似たイメージ 9c027e1a2a67967d26c6f4434f4086b5 IROHA.txt enc: 共通鍵暗号による暗号化、復号化の実行†
まず暗号化の例 $ cat IROHA.txt いろはにほへとちりぬるを(中略)ひもせす! $ openssl enc -aes256 -salt -in IROHA.txt -out enctxt.bin enter aes-256-cbc encryption password: # 今回は123456789[Enter]で Verifying - enter aes-256-cbc encryption password: # 同じく123456789[Enter]で $ cat -v IROHA.txt M-cM-^AM-^DM-cM-^BM-^MM-cM-^AM-/M-cM-(以下省略) ご覧の通り、暗号文enctxt.binはバイナリファイルです。 $ openssl enc -d -aes256 -in enctxt.bin -pass pass:123456789 いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす! なお、後述の公開鍵もそうですが、 補足:公開鍵の生成~証明書作成の流れ†ここから先、かなり混乱したので、一旦整理しておきます。 genrsa: RSA鍵の生成†公開鍵方式の一つ、RSA鍵を生成するオプションです。
以下、実行例 $ openssl genrsa -camellia256 -out private_key.pem -rand /dev/urandom -passout pass:123456789 2048 2048 semi-random bytes loaded Generating RSA private key, 2048 bit long modulus ....+++ ..............................................+++ e is 65537 (0x10001) $ cat private_key.pem -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: CAMELLIA-256-CBC,E8B472860EDE6C7E3C85EA32FAE8EB3B txKaxEtSwc2jKnqFJL5CfyYHtaHqr4IbDbAvrqRE4kBuUcfGUQ7p4jtJK3pF3Qqn (長いので中略) W8C6EfPf5GUr4zs4r8gQZka0NeyzyfDr1y7BzilBus0GXYwluLssgtJ40biHZAol Mq/RzGRngcn5MTiFxbR/fT+ebRMo/tvKz6ugUdE+z358jFFUrlmPzTHymM6d33tP -----END RSA PRIVATE KEY----- $ 普通はやらないですが(セキュリティ上、危ないので)、 rsa: 秘密鍵の操作、公開鍵の生成†
前述の秘密鍵から公開鍵をRSAで生成します。 $ openssl rsa -in private_key.pem -pubout -out pub_key.pem -passin pass:123456789 writing RSA key $ cat pub_key.pem -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtAI+xWJkfafdlDrprefP (中略) kU8DCf1QYMIEt0n6NxxKiNFQK4rhMM2Fqc775mKKtTmTIWGDUFo2GDs5faPca7qf /QIDAQAB -----END PUBLIC KEY----- $ openssl rsa -text -pubin -in pub_key.pem Public-Key: (2048 bit) Modulus: 00:b4:02:3e:c5:62:64:7d:a7:dd:94:3a:e9:ad:e7: (中略) 93:21:61:83:50:5a:36:18:3b:39:7d:a3:dc:6b:ba: 9f:fd Exponent: 65537 (0x10001) writing RSA key -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtAI+xWJkfafdlDrprefP (中略) kU8DCf1QYMIEt0n6NxxKiNFQK4rhMM2Fqc775mKKtTmTIWGDUFo2GDs5faPca7qf /QIDAQAB -----END PUBLIC KEY----- $ rsautl: 鍵を使った運用†
以下、動作確認の例 $ echo "OpenSSL PrivateKey Test" |\ openssl rsautl -encrypt -inkey private_key.pem -out pri_enc.data -passin pass:123456789 $ openssl rsautl -in pri_enc.data -decrypt -inkey private_key.pem -passin pass:123456789 OpenSSL PrivateKey Test 次に、公開鍵暗号方式としての動作確認 $ echo "OpenSSL PublicKey Test" |\ openssl rsautl -encrypt -pubin -inkey pub_key.pem -out pub_enc.data $ openssl rsautl -in pub_enc.data -decrypt -inkey private_key.pem -passin pass:123456789 OpenSSL PublicKey Test req:証明書署名要求CSR(Certificate Signing Request)を作成する†
今さらですが、そもそもCSRって一体何物かというと、
では前述の秘密鍵からCSRを生成してみます。 $ openssl req -new -key private_key.pem -out test.csr -passin pass:123456789 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) [XX]:JP #日本(JP)でEnter State or Province Name (full name) []:Shimane #島根でEnter Locality Name (eg, city) [Default City]:Izumo #出雲でEnter Organization Name (eg, company) [Default Company Ltd]:Yaoyorozu, Inc. #八百万でEnter Organizational Unit Name (eg, section) []:Jashin #うーん、センスない。Enter Common Name (eg, your name or your server's hostname) []:null-i.net #サイト名でEnter Email Address []: #メールアドレスは省略して、Enter Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: #拡張オプションは今回は要らない。そのままEnter An optional company name []: #おなじく、そのままEnter $ cat test.csr -----BEGIN CERTIFICATE REQUEST----- MIICtDCCAZwCAQAwbzELMAkGA1UEBhMCSlAxEDAOBgNVBAgMB1NoaW1hbmUxDjAM BgNVBAcMBUl6dW1vMRgwFgYDVQQKDA9ZYW95b3JvenUsIEluYy4xDzANBgNVBAsM (中略) d89fK+4M9lgwJXRFgPsyCT8djcR/dBkYPbFzfvVVad4JkuSw1AaH7gUGQ3pvoYFx 2v5zb30VzM7BnUsOGFaEaEl5bB2EjIjt -----END CERTIFICATE REQUEST----- $ openssl req -in test.csr -text -noout Certificate Request: Data: Version: 0 (0x0) Subject: C=JP, ST=Shimane, L=Izumo, O=Yaoyorozu, Inc., OU=Jashin, CN=null-i.net Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:ba:e8:65:4b:17:bd:d1:93:87:25:3c:c7:fc:2a: (以下省略) 対話式で入れている各値のデフォルト値は 環境変数 OPENSSL_CONF で指定した設定ファイルから読み込まれますが、 元になる鍵もまとめて作るなら -newkeyが使えます。 $ openssl req -newkey rsa:2048 -out test2.csr 自分自身がルートCAとなるならば必要なのはルート証明書なので、作成オプションは-x509に変わります。 $ openssl req -x509 -new -key private_key.pem -out cacert.pem -passin pass:123456789 (作る部分は前述の req -new と同じなので省略) (次はのコマンドは、中身の確認) $ openssl x509 -in cacert.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 14270986686045102946 (0xc60cbac7b00c2362) Signature Algorithm: sha1WithRSAEncryption Issuer: C=JP, ST=Shimane, L=Izumo, O=Yaoyorozu Inc., OU=Jashin, CN=null-i.net Validity Not Before: Dec 27 04:43:16 2014 GMT Not After : Jan 26 04:43:16 2015 GMT Subject: C=JP, ST=Shimane, L=Izumo, O=Yaoyorozu Inc., OU=Jashin, CN=null-i.net Subject Public Key Info: (以下省略) ちなみに有効期限(-days)未指定だと、デフォルトのValidityが1カ月っぽいですね。 x509: 証明書の確認や操作を行う†
試しにジオトラストから証明書を取得して、表示してみたのが以下です。 $ cat GeoTrust_Global_CA.pem -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT (中略) hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== -----END CERTIFICATE----- $ openssl x509 -in GeoTrust_Global_CA.pem -text Certificate: Data: Version: 3 (0x2) Serial Number: 144470 (0x23456) Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA Validity Not Before: May 21 04:00:00 2002 GMT Not After : May 21 04:00:00 2022 GMT Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df: (以下省略) ca: 認証局の証明書を管理する†なんか、このオプションあんまり個人で使う機会は無い気がします。
CSRから証明書を発行するにはこう。 CAのもつデータベース(configのdatabaseキーで指定)が更新される。 openssl ca -in test.csr -passin pass:CAの秘密鍵のパスワード あるいは openssl ca -passin pass:CAの秘密鍵のパスワード -infiles CSR1個目 CSR2個目 ... ここで出た標準出力、あるいは-outや-outdirで出て来た証明書を、CSR発送者に返してあげることになります。 失効は以下。 openssl ca -revoke /etc/pki/CA/newcerts/証明書 あと失効リスト(CRL)の作成と、その内容の確認 $ openssl ca -gencrl -out test.crl $ openssl crl -in test.crl -text -noout s_client: SSLクライアントの実行†
とりあえず、googleに繋いでみる場合 $ openssl s_client -connect www.google.co.jp:443 CONNECTED(00000003) depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority verify return:1 depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA verify return:1 depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2 verify return:1 depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com verify return:1 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com i:/C=US/O=Google Inc/CN=Google Internet Authority G2 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2 i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority --- Server certificate -----BEGIN CERTIFICATE----- MIIfIzCCHgugAwIBAgIIEXRBFbfctNAwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE (とても長いので中略) Start Time: 1419747551 Timeout : 300 (sec) Verify return code: 0 (ok) --- こんなかんじで、一旦ここで出力が止まります。そこで、
今回は、HTTPなので以下の例では 「GET~close[Enter][Enter]」と入力して、サイトを取得し切断を試みます。 「HTTP/1.1 200 OK」から先が応答です。 (上記のつづき) --- GET https://www.google.co.jp/ HTTP/1.1 Host: www.google.co.jp Connection: close HTTP/1.1 200 OK Date: Sun, 28 Dec 2014 06:19:22 GMT (中略) Connection: close <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja">< (以下省略) ・・・まぁ、だいぶ省略しましたが。 s_server: SSLサーバの再現†
試しに、仮想のWebサーバを立てます。 $ openssl s_server -accept 12345 -www -cert server.crt -key server.key Using default temp DH parameters Using default temp ECDH parameters ACCEPT で、Webブラウザで「https://上記コマンドを入力したサーバ:12345/」にアクセスすると s_server -accept 12345 -www -cert server.crt -key server.key Secure Renegotiation IS supported Ciphers supported in s_server binary TLSv1/SSLv3:ECDHE-RSA-AES256-GCM-SHA384TLSv1/SSLv3:ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1/SSLv3:ECDHE-RSA-AES256-SHA384 TLSv1/SSLv3:ECDHE-ECDSA-AES256-SHA384 TLSv1/SSLv3:ECDHE-RSA-AES256-SHA TLSv1/SSLv3:ECDHE-ECDSA-AES256-SHA (以下省略) では、次に -HTTPで起動した場合。事前に test.html は作成しておきます。 $ cat -v test.html HTTP/1.1 200 OK^M Content-Length: 40^M ^M <html><body> hello world </body></html> $ openssl s_server -accept 12345 -HTTP -cert server.crt -key server.key Using default temp DH parameters Using default temp ECDH parameters ACCEPT test.htmlの中身が復帰改行(上記で「^M」)になっていることに注意。HTTPの構文上のルールです。 これらを全部手入力でやる場合が以下。(-wwwも-HTTPも指定せずに起動) $ openssl s_server -accept 12345 -cert server.crt -key server.key Using default temp DH parameters Using default temp ECDH parameters ACCEPT この状態で、「https://上記コマンドを入力したサーバ:12345/test.html」にアクセスすると、 opensslを実行している画面上には以下の表示が出力されます -----BEGIN SSL SESSION PARAMETERS----- MIGDAgEBAgIDAQQCAC8EIB27C9y3O0qehMdtgcZDNSNjwOU8U1iNbbsQ3gGq0sGU (中略) AjWhBgIEVJ+xv6IEAgIBLKQGBAQBAAAApgwECm51bGwtaS5uZXQ= -----END SSL SESSION PARAMETERS----- Shared ciphers:AES128-SHA:AES256-SHA:(中略) CIPHER is AES128-SHA Secure Renegotiation IS supported GET /test.html HTTP/1.1 Accept: text/html, application/xhtml+xml, */* Accept-Language: ja User-Agent: Mozilla/X.0 (compatible; MSIE X.0; Windows NT X.0; Trident/X.0) Accept-Encoding: gzip, deflate Host: 起動したサーバ名:12345 Connection: Keep-Alive リクエストの内容が全て表示されて、サーバ側の入力待ちになるので、何らかを入力します。
Webブラウザはサーバの応答を待っている状態のままなので、以下を慌てて入力。 HTTP/1.1 200 OK Content-Length: 37 Connection: close <html><body> HELLO!! </body></html> すると、WebブラウザにHELLOが出ます。 そんなこんなで†コマンドのオプションは上記以外にも山ほどあるので、省略。 |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||