TLSの暗号化方式について考える(CHACHA20_POLY1305とは)

少し前にngixでWebサーバーを立てて、SPDYを利用するためにTLSの設定をしていました。

TLS設定時に出てくるがTLSのバージョンと暗号化方式。

バージョンについてはSSL3.0はもうやめて、最低TLS1.0にしましょうというのが常識みたいなので特に悩むことはありません。TLS1.2,1.1,1.0を使えるようにしておけばOK。

が、問題は暗号化方式。なんかいっぱいあってよくわからない。

結論としてはこの記事を見て、見よう見まねで設定しました。

 

この設定をするまでに色々調べました。

ChromeでURLの横の鍵マークをクリックすると、簡単に各サイトの暗号化方式が見れて、さらに「新しい暗号化」だとか「古い暗号化」だとかまで教えてくれます。

とりあえず、何が新しくて何が古いのか謎だったので検索したら、Chromiumのソースを見て確認している人がいました。

※2015.3時点のものなので、将来的に変わる可能性はあります

 

この条件で、「最新の暗号化」と表示されてかつ今一番使われているのが、この暗号化です。AES_128_GCM

最初にURLを出した設定方法に従った場合もこれになります。

f:id:noobow34:20150524141301p:plain

 

じゃあ天下のGoogle様はどうしてるんだろう?インターネットについて日々考えまくってるGoogle様と同じ設定にしておけば安心だろうと考えたわけです。

f:id:noobow34:20150606135312p:plain

CHACHA20_POLY1305???なんだこれは?

ほかのサイトを色々見ても出てこなかった方式です。でもきっとGoogleが使うぐらいだから安全なものではあるのでしょう。調べてみました。

Poly1305-AES - Wikipedia

Googleは、共通鍵暗号としてChaCha20、メッセージ認証符号としてPoly1305を組み合わせたものを、RC4に代わるインターネットセキュリティで利用可能なストリーム暗号として提唱している。Google ChromeおよびGoogleウェブサービスにおけるTLS/SSL通信 (https) においてChaCha20-Poly1305が実装されている。

 Poly1305-AESは様々なCPUで高速に計算可能である。

どうやら、Googleが提唱している安全かつ計算が高速な暗号化のようです。

 

じゃあnginxでこの設定にしようと思ったのですが、いくら探しても設定方法が出てきませんでした。

そこで調べてみると

  • OpenSSLにはまだ標準では実装されていない(nginxはビルドにOpenSSLが必要なので暗号化部分はOpenSSLを使ってるはず。なのでOpenSSLに実装されてない暗号化はnginでは使えない)
  • LibreSSLには実装されている
  • BoringSSLにも実装されている 

BoringSSLはGoogleがOpenSSLからフォークしたものなので、GoogleのWebサーバーにもきっとBorignSSLを使ってCHACHA20_POLY1305を提供しているのでしょう。ちなみにブラウザ側(Chrome)は、使用しているOSSとしてBoringSSLがしっかりと書かれています。

ちなみにLibreSSLを使ってnginxをビルドすれば、nginxでもCHACHA20_POLY1305が使えるようです。

NginxとLibreSSLを組み合わせて使用する - Qiita

nginx - Built against LibreSSL

OpenSSLが対応すれば、きっとnginxでも標準で使えるようになると思うのですが、対応予定は調べてもイマイチわかりませんでした。が、CloudFlareがOpenSSLを対応させるパッチを公開していることがわかりました。

このブログ記事で、やはりより高速な暗号化方式として紹介されてて、AES_128_GCMとCHACHA20_POLY1305の速度比較も載っています。

AES-128-GCM: 41.6ms

ChaCha20-Poly1305: 13.2ms

 ちなみに、CLOUDFLAREがパッチを開発していることからもわかるように、CloudFlareを通じて提供されているWebサイトではCHACHA20_POLY1305が使われていました。

例えばこれ→ https://www.airtahitinui.com/jp-ja

今のところ、GoogleとCloudFlare以外で対応サイトは見つかりませんでした。

 

先日紹介したCaddyは、簡単に使えるのが売りなのでTLS使用時に暗号化方式の設定をする必要が無いのですがAES_128_GCMになります。

こちらもなんとかCHACHA20_POLY1305にできないかと思いソースを読んでみましたが、golangのcrypto/tlsというパッケージを使って暗号化しているようで、さらにgolangの仕様を調べてみましたが、まだCHACHA20_POLY1305が実装されていませんでした。

 

ということで、golangやOpenSSLが早く標準で対応して、Apacheやnginxで使えるようになって、性能の良い方式がドンドン広がっていけばいいなと思いました。