httpsだからというだけで安全?調べたら怖くなってきたSSLの話!?

  • 2248
    いいね
  • 8
    コメント

課題

サイトをを立ち上げるときに当然のごとくSSL証明書をベンダーから購入して設置していたが、いざセキュリティ診断等でチェックしてもらうとSSLについての指摘を何件か受けてみた。なんでだろうと思いながらも、さらに最適なSSL設定は?と聞かれてそういえばあまり昔から手を入れたことなかったなと思い調べてみた

SSL通信が確立するまでの概要フロー

SSL通信について再度おさらい

ssl2.png

Nginxを元にしたSSLの設定

nginxのHTTPS サーバの設定を参考に、たった2行だけどSSLを考えてみる。書き方は違えどもapacheも概念は一緒のはず。

ssl_protocols        SSLv3 TLSv1;
ssl_ciphers          HIGH:!ADH:!MD5;

SSLプロトコルの種類を確認

wikiよりプロトコルの種類を確認してみる。

略称 正式名称 開発元
SSL Secure Socket Layer ネットスケープコミュニケーション
TLS Transport Layer Security IETF

バージョン毎の概要を確認してみる。

バージョン 安全性 概要
SSL1.0 最初のSSLとして設計したが、設計レビューの時点でプロトコルの脆弱性が発見されたため破棄されている。
SSL2.0 SSL1.0の問題を修正して設計後、1994年にSSL2.0として発表。その後、いくつか脆弱性が発見されてSSL3.0が登場するが、未使用でもSSL2.0が有効な状態の場合に提示する最弱のアルゴリズムを使用させるダウングレード攻撃などを受ける可能性があるので、明示的に無効にする必要がある。
SSL3.0 SSL2.0の問題を修正して機能追加も行い1995年にSSL3.0として発表。ただ、古くなってきている。CVE-2014-3566で脆弱性が発生したため明示的に無効にする必要がある。
TLS1.0 SSL3.0とTLS1.0の両者間には正確な互換性はないがほぼ同じ。CVE-2011-3389(BEAST)による一部脆弱性を含む。
TLS1.1 TLS 1.0からの変更点は、新しく発見された攻撃手法に対する耐性の強化が中心である。
TLS1.2 ハッシュのアルゴリズムにSHA-256が追加されたほか、ブロック暗号について、従来のCBCモードだけではなく、GCM、CCMといった認証付き暗号が利用可能となった。
TLS1.3 ? [ドラフト]インターネット環境の変化とTLS1.2までの暗号化強度不足を改善するため2016年中に仕様化完了を目指している(らしい)

そのため、SSLv1 / SSLv2 / SSLv3 は脆弱性があるので、 現時点で使用できるものはTLSv1以上

SSL_Ciphersについて調べてみる...

HIGH:!ADH:!MD5;と書いてはあるものの、「HIGHグループでADHとMD5を使わない」という読み方であってるのか?調べてみるとOpenSSLで確認出来るらしい

$ openssl ciphers -v 'HIGH:!ADH:!MD5;'

result
DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
DHE-DSS-AES256-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(256)  Mac=SHA1
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA1
DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH       Au=DSS  Enc=Camellia(256) Mac=SHA1
AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
CAMELLIA256-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(256) Mac=SHA1
PSK-AES256-CBC-SHA      SSLv3 Kx=PSK      Au=PSK  Enc=AES(256)  Mac=SHA1
EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
PSK-3DES-EDE-CBC-SHA    SSLv3 Kx=PSK      Au=PSK  Enc=3DES(168) Mac=SHA1
KRB5-DES-CBC3-SHA       SSLv3 Kx=KRB5     Au=KRB5 Enc=3DES(168) Mac=SHA1
DHE-RSA-AES128-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA1
DHE-DSS-AES128-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(128)  Mac=SHA1
DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(128) Mac=SHA1
DHE-DSS-CAMELLIA128-SHA SSLv3 Kx=DH       Au=DSS  Enc=Camellia(128) Mac=SHA1
AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
CAMELLIA128-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(128) Mac=SHA1
PSK-AES128-CBC-SHA      SSLv3 Kx=PSK      Au=PSK  Enc=AES(128)  Mac=SHA1

なんかいっぱい出てきた

暗号方法の内容を1つ1つ確認

まずは1行目の DHE-RSA-AES256-SHA   SSLv3  Kx=DH  Au=RSA  Enc=AES(256)  Mac=SHA1 を読み解いてみる。このサイトによると下記のようだ。

Column 内容 原文
DHE-RSA-AES256-SHA 暗号化スイート cipher suite name
kx 鍵交換をする時のアルゴリズム the algorithm used for key exchange
Au 鍵認証のためのアルゴリズム the algorithm for authentication
Enc 暗号化通信に使われる一括暗号化アルゴリズム the bulk encryption algorithm
Mac メッセージ認証符号 the message authentication code (MAC) algorithm

いろいろアルゴリズムを使ってるのはわかったもののどこで使ってるんだ?

それぞれどこで使ってるの?

ssl_alg.png

主な暗号化アルゴリズム

種類がたくさんありますが、一部集めてみました。

アルゴリズム 用途 ブロック長 鍵長 概要
RSA Au:公開鍵暗号[署名] 1024-4096 bit [主流] 桁数が大きい合成数の素因数分解問題が困難であることを安全性の根拠とした公開鍵暗号の一つである
DSA Au:公開鍵暗号[署名] 1024bit [まだ少ない?] OpensslでみるとDSSと表記されている。有限体上の離散対数問題の困難性を安全性の根拠としており、現仕様においては有効な攻撃方法が示されたことはないものの、理論上はいまだ署名としての最も高い安全性を満たすことが証明されていない。
ECC Au:公開鍵暗号[署名] [注目株] EC-DLPを解く準指数関数時間アルゴリズムがまだ見つかっていないため、それが見つかるまでの間は、ベリサインによると12分の1の鍵長で、現在主流のRSA 2048の1.5倍の強度を実現できるため同レベルの安全性をより短い鍵で実現でき、処理速度も速いことをメリットとして、ポストRSA暗号として注目されている。
DH Kx:公開鍵暗号[鍵交換] [主流] DHパラメータは証明書に書かれている物を使う。よって、static DHとも呼ばれる。
ECDH Kx:公開鍵暗号[鍵交換] [注目株] Elliptic curve Diffie–Hellmanの略。楕円曲線上でDiffie-Hellman(DH)鍵共有を⾏う楕円DH(ECDH)⽅式。PFS(perfect forward secrecy)をサポートしていない。
ECDSA Kx:公開鍵暗号[鍵交換] [注目株] Elliptic Curve Digital Signature Algorithmの略。楕円曲線上でDigital Signature Algorithm(DSA)を実現する楕円DSA(ECDSA)⽅式。PFS(perfect forward secrecy)をサポートしていない。
ECDHE Kx:公開鍵暗号[鍵交換] [注目株] Ephemeral Elliptic curve Diffie–Hellmanの略。DHパラメータを通信時に動的に作成する。楕円曲線上でDiffie-Hellman(DH)鍵共有を⾏う楕円DH(ECDH)⽅式。EはEphemeral(一時的)を意味している。PFS(perfect forward secrecy)をサポートしている。
DES Enc:共通鍵暗号 64bit 56bit [強度弱] 現代においては十分な強度とは言えなくなっています。並列処理可能なDES破り専用プロセッサも存在し、 資金さえ投入すれば数時間~数日というレベルで解読することができます。
AES Enc:共通鍵暗号 128bit 128/192/256bit [注目株] DESに代わる次世代の暗号標準。暗号強度、高速性に優れてます。
RC4 Enc:共通鍵暗号 可変長 ストリーム暗号 [脆弱性あり] RC4はストリーム暗号としては大変広く使われていますが、同時にいろんな脆弱性があることでも知られてきている。WEPやSSL/TLSで広く使われてますが、WEPが脆弱であることが広く知られているのに比べ、SSL/TLSでのRC4はそれほど恐れられていませんでした。
MD5 Mac:ハッシュ関数 [脆弱性あり] 任意長メッセージから128ビットの一方向ハッシュ値を生成します。SLOTH攻撃(CVE-2015-7575)による影響があります。
SHA-1 Mac:ハッシュ関数 [脆弱性あり] 160ビットメッセージダイジェストアルゴリズム。SLOTH攻撃(CVE-2015-7575)による影響があります。
SHA-2 Mac:ハッシュ関数 [主流] 224ビット・256ビット・384ビット・512ビットのメッセージダイジェストアルゴリズム
SHA-3 Mac:ハッシュ関数 [次世代?]米国の国立標準技術研究所(NIST)は,2012年10月2日に次世代の暗号学的ハッシュ関数の標準を決めるSHA-3として Keccak を選定した。しかし、その後、SHA-2への有望な攻撃法は2015年8月現在発表されていないため結果としてSHA-2の代替の用意が重要ではなくなるなど、状況が変化している

暗号化利用モード

暗号化利用モードとは、ブロック長よりも長いメッセージを暗号化するための方式。

略称 名称 利用モード 概要
ECB Electronic CodeBook 秘匿用 [強度弱]各ブロックを1つずつ暗号化処理をする。最もシンプルな方式
CBC Cipher Block Chaining 秘匿用 [脆弱性あり]各平文のブロックは暗号化される前に、前の暗号化ブロックでXORすることを繰り返す。最初のブロックは暗号と無関係なIV(Initialization Vector)を使用して暗号化する。BEAST攻撃によりデータが復号化される可能性あり。
CTR CounTeR 秘匿用 [主流]IVではなくカウンターの値をインクリメントしつつブロック暗号処理したものに平文ブロックをXORする。
CCM Counter with CBC-MAC 認証用 TLS1.2で使用可能。カウンター (CTR)モードとCBC-MACモードを組み合わせたものであり、前者が暗号化に、後者が認証に用いられる。同一の鍵を暗号化と認証の双方に用いることができることができ、暗号化に用いられたカウンター値が認証で用いられる初期化ベクトルと衝突することがない
GCM Galois/Counter Mode 認証用 [主流]TLS1.2で使用可能。GCMは認証付き暗号の一つであり、データ保護と認証(完全性確認)の双方に利用できる。遅延、オーバーヘッドが少ないことから、パケット化されたデータの保護に適している。

PFS(Perfect Forward Secrecy)について

SSL/TLS & Perfect Forward Secrecy

名称 略称 概要 Kx
Without forward secrecy - 認証と同じ公開暗号を使用した場合に、攻撃者が暗号化した通信を全部記録していたとすると、後に認証に使用していた秘密鍵が漏洩してしまうと復号化が出来てしまう。 FS・PFS以外 AES128-SHA
Forward Secrecy FS 認証用の鍵と鍵交換用の鍵が異なるので、通信の漏洩の可能性が低くなります。RSA 2048bitと比べるとサーバへのCPU負荷が3.1倍程度に増加するようです。 DH / ECDH DH-RSA-AES128-SHA
Perfect Forward Secrecy PFS FSに比べて、一定時間後に定期的に異なる鍵交換を行うため、より漏洩の可能性を低く出来ます。また、RSA 2048bitと比べてもサーバへのCPU負荷は微増のようです。 DHE / ECDHE DHE-RSA-AES128-SHA

暗号化方法はたくさんあるけどナニを選べばいいの?

SSL/TLS Deployment Best Practices というのがある

Use Secure Protocols

  • SSL v2 is insecure and must not be used.

  • SSL v3 is very old and obsolete. Because it lacks some key features and because virtually all clients support TLS 1.0 and better, you should not support SSL v3 unless you have a very good reason.

  • TLS v1.0 is largely still secure; we do not know of major security flaws when they are used for protocols other than HTTP. When used with HTTP, it can almost be made secure with careful configuration.

  • TLS v1.1 and v1.2 are without known security issues.

SSLプロトコル

  • SSLv2は使用しない
  • SSLv3は非常に古く廃止されています。いくつかの主要機能が不足しており、事実上すべてのクライアントがTLS1.0をサポートしている。そのため、よっぽど良い理由がない限りはSSLv3をサポートするべきではない
  • TLS v1.0の大部分はまだ安全です。HTTPを使用するときに、キチンと設定をすればセキュアに出来る
  • TLS v1.1 とTLS v1.2はセキュリティに関する問題が発見されていない

Use Secure Cipher Suites

  • Anonymous Diffie-Hellman (ADH) suites do not provide authentication.

  • NULL cipher suites provide no encryption.

  • Export key exchange suites use authentication that can easily be broken.

  • Suites with weak ciphers (typically of 40 and 56 bits) use encryption that can easily be broken.

  • RC4 is weaker than previously thought. You should remove support for this cipher in the near future.

  • 3DES provides only 108 bits of security (or 112, depending on the source), which is below the
    recommended minimum of 128 bits. You should remove support for this cipher in the near future.

暗号化スイート

  • ADH(Anonymous Diffie-Hellman)は認証機能を提供していない
  • Null暗号化スイートは暗号化しない
  • Export鍵交換は簡単に解除される認証機能を使っている
  • 特に40, 56bitの弱い暗号スイートは簡単に暗号化を解除される
  • RC4は以前考えられてたよりも弱い。近い将来、サポート対象外にするべき。
  • 3DESは108または112bitsしか提供していない。最低でも128bits以上が推奨されるので、近い将来サポート対象外にするべき。

セキュリティに余念のない有名企業はどうしているのか?

Netcraftが2013年9月に調査した情報によると下記のような対応状況です。2014年3月にwww.facebook.comを確認したところ、ECDHE-RSA-AES128-GCM-SHAになっていたので各社変わっている可能性はありそうです。

ssl_list.png

最近発生した主なSSLの脆弱性

名称 CVE 発生日 概要 対応概要
Beast CVE-2011-3389 2011/9/6 CBC mode脆弱性
TLS heartbleed CVE-2014-0160 2014/4/7 TLS脆弱性 opensslをupdate
CCS injection CVE-2014-0224 2014/6/5 CCS脆弱性 opensslをupdate
POODLE CVE-2014-3566 2014/10/14 SSLv3脆弱性 SSLv3を無効にする
複数脆弱性 CVE-2015-0291等(全14個) 2015/3/19 複数脆弱性対応 opensslをupdate
Altチェイン証明書偽造 CVE-2015-1793 2015/7/6 証明書偽造 opensslをupdate
SLOTH攻撃 CVE-2015-7575 2016/1/8 TLS脆弱性(ハッシュ衝突) MD5とSHA-1を使用しない
DROWN CVE-2016-0800 2016/3/1 クロスプロトコル攻撃 SSLv2を無効にする
SWEET32 CVE-2016-2183 2016/8/24 誕生日攻撃 3DESなど64bitsブロック暗号の停止
SHAttered CVE-2005-4900 2017/2/23 ハッシュ衝突攻撃 SHA-256, SHA-3への移行

結局今のところどのような設定が良さそうか

最初に記載したNginxの公式にサイトに書いてあったよりも、脆弱性があるまたは弱い暗号化を除いて、明示的に使用する暗号化スイートを設定するのが良さそう。 あくまで例なのでサイトに合ったものを設定してください。

  • 最新版のopenssl [CVE-2014-0160 / CVE-2014-0224]
  • 128bit以上
  • Enc: AES
  • Au: RSA
  • Kx: DH/ECDH/ECDHE (FS以上)
  • 暗号化利用モード: GCM
  • SSLv3以下を無効 [CVE-2014-3566]
ssl on;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:
            DH+AESGCM:ECDH+AES256:DH+AES256:
            ECDH+AES128:DH+AES:
            !EXPORT:!DES:!3DES:!MD5:!DSS;

対応暗号スイートを確認

$openssl ciphers -v 'ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!EXPORT:!DES:!3DES:!MD5:!DSS'

ローカルだとこのような感じで出てきた

result
ECDHE-RSA-AES256-GCM-SHA384   TLSv1.2 Kx=ECDH       Au=RSA   Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH       Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDH-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH/RSA   Au=ECDH  Enc=AESGCM(256) Mac=AEAD
ECDH-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH/ECDSA Au=ECDH  Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256   TLSv1.2 Kx=ECDH       Au=RSA   Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH       Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDH-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH/RSA   Au=ECDH  Enc=AESGCM(128) Mac=AEAD
ECDH-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH/ECDSA Au=ECDH  Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384     TLSv1.2 Kx=DH         Au=RSA   Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256     TLSv1.2 Kx=DH         Au=RSA   Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES256-SHA384       TLSv1.2 Kx=ECDH       Au=RSA   Enc=AES(256)    Mac=SHA384
ECDHE-ECDSA-AES256-SHA384     TLSv1.2 Kx=ECDH       Au=ECDSA Enc=AES(256)    Mac=SHA384
ECDHE-RSA-AES256-SHA          SSLv3   Kx=ECDH       Au=RSA   Enc=AES(256)    Mac=SHA1
ECDHE-ECDSA-AES256-SHA        SSLv3   Kx=ECDH       Au=ECDSA Enc=AES(256)    Mac=SHA1
ECDH-RSA-AES256-SHA384        TLSv1.2 Kx=ECDH/RSA   Au=ECDH  Enc=AES(256)    Mac=SHA384
ECDH-ECDSA-AES256-SHA384      TLSv1.2 Kx=ECDH/ECDSA Au=ECDH  Enc=AES(256)    Mac=SHA384
ECDH-RSA-AES256-SHA           SSLv3   Kx=ECDH/RSA   Au=ECDH  Enc=AES(256)    Mac=SHA1
ECDH-ECDSA-AES256-SHA         SSLv3   Kx=ECDH/ECDSA Au=ECDH  Enc=AES(256)    Mac=SHA1
DHE-RSA-AES256-SHA256         TLSv1.2 Kx=DH         Au=RSA   Enc=AES(256)    Mac=SHA256
DHE-RSA-AES256-SHA            SSLv3   Kx=DH         Au=RSA   Enc=AES(256)    Mac=SHA1
ECDHE-RSA-AES128-SHA256       TLSv1.2 Kx=ECDH       Au=RSA   Enc=AES(128)    Mac=SHA256
ECDHE-ECDSA-AES128-SHA256     TLSv1.2 Kx=ECDH       Au=ECDSA Enc=AES(128)    Mac=SHA256
ECDHE-RSA-AES128-SHA          SSLv3   Kx=ECDH       Au=RSA   Enc=AES(128)    Mac=SHA1
ECDHE-ECDSA-AES128-SHA        SSLv3   Kx=ECDH       Au=ECDSA Enc=AES(128)    Mac=SHA1
ECDH-RSA-AES128-SHA256        TLSv1.2 Kx=ECDH/RSA   Au=ECDH  Enc=AES(128)    Mac=SHA256
ECDH-ECDSA-AES128-SHA256      TLSv1.2 Kx=ECDH/ECDSA Au=ECDH  Enc=AES(128)    Mac=SHA256
ECDH-RSA-AES128-SHA           SSLv3   Kx=ECDH/RSA   Au=ECDH  Enc=AES(128)    Mac=SHA1
ECDH-ECDSA-AES128-SHA         SSLv3   Kx=ECDH/ECDSA Au=ECDH  Enc=AES(128)    Mac=SHA1
DHE-RSA-AES128-SHA256         TLSv1.2 Kx=DH         Au=RSA   Enc=AES(128)    Mac=SHA256
DHE-RSA-AES128-SHA            SSLv3   Kx=DH         Au=RSA   Enc=AES(128)    Mac=SHA1

Apacheの場合はこのような感じになると思う(Apache 2.4以降ではSSLv2が除外)

SSLProtocol ALL -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite ECDHE+RSAGCM:ECDH+AESGCM:
               DH+AESGCM:ECDH+AES256:DH+AES256:
               ECDH+AES128:DH+AES:
               !EXPORT:!DES:!3DES:!MD5:!DSS

設定を生成してくれるサービスもある!

SSLがキチンと設定されているかテストするには

SSL Server TestまたはGlobalSign SSL チェックで暗号化強度やブラウザのサポート具合などもチェックできます。また、コンソールでチェックするのにtestssl.sh: Testing TLS/SSL encryptionも便利です。
簡易的には下記でもSSLの状態が確認出来る

$ openssl s_client -host [URL/HOST NAME] -port 443 -ssl3

まとめ

たかが2行設定するのにここまで色々あるとは...まだ関連する技術がありそうなので日々精進が必要そうです。ただ、今回わかったことは単にコピペで設定すると、かなりのセキュリティホールになりそうなのでちゃんとテストして設定しようと。

参考資料

電子政府における調達のために参照すべき暗号のリスト(CRYPTREC暗号リスト)
http://www.cryptrec.go.jp/list.html
http://search.e-gov.go.jp/servlet/PcmFileDownload?seqNo=0000097652

Hardening Your Web Server’s SSL Ciphers
https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/

IE使うならVista以降が無難、SSLの暗号強度調査結果から
http://internet.watch.impress.co.jp/docs/event/iw2009/20091126_331592.html

SSL/TLSでBEASTを恐れてRC4を優先するのは危ない
http://tetsutalow.hateblo.jp/entry/2013/04/02/053927