TLSとATSについての覚書


iOS9から導入されたATS(App Transport Security)ではサーバ側のhttpsの設定で、単にHTTPS通信をonにすればいいというわけではなくサーバ証明書や暗号化スイートについても細かい要件が定義されている。サーバ側の設定を見直すときに、TLSについて調べなおしたのでまとめる.

## TLSのおさらい

RFC5246
https://tools.ietf.org/html/rfc5246

### TLSハンドシェイク

クライアント側でのサーバ証明書によるサーバの認証と、公開鍵暗号を用いたクライアント-サーバ間での共通鍵交換が行われる。サーバ側でのクライアント認証はOptional.

手順は以下のような感じ.

1. Client: 動作仕様の送信(通信可能な、TLSバージョンや暗号スイートなど)
2. Server: TLSプロトコルバージョン、暗号スイートの決定. サーバ証明書の返却.
3. Client: サーバ証明書の検証. 共通鍵暗号で用いる鍵交換.
4. Server: クライアントから送られてきた鍵の検証. 暗合化された'Finished'文字列の送信.
5. Client: 'Finished'文字列の複合と検証. アプリケーションデータの送信開始.

この大枠の手順を定めているのがTLSということになる.

### 暗号スイート

TLSでは、認証、暗号化、データ整合性保証を行うための大枠を定義している一方、内部的に用いる著名・暗号アルゴリム等は様々なものを利用できる。内部的に用いる各種アルゴリズムの組み合わせのことを暗号スイート(cipher suite)と呼ぶ。opensslコマンドでcipherの例を確認できる.

```bash

#openssl ciphers -v
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
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
...
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
...
```

左から
* 暗号スイートの名前
* プロトコルのバージョン
* Kx: 鍵交換の方法
* Au: サーバ認証の方法
* Enc: 暗号化の方法
* Mac: メッセージ認証のハッシュアルゴリズム

## Mozillaのサーバ設定ガイド

https://wiki.mozilla.org/Security/Server_Side_TLS


用途に合わせたTLSの設定のガイドがコンパクトにまとまっている.安全性と古い端末に対する互換性、安全性とパフォーマンス最適化のトレードオフをどこらへんで調整すれば良いかが解説されている.

また、主要なhttpsサーバの設定ファイルを自動で生成してくれるページもあって嬉しい.


## ATS 
 
ATS(App Transport Security)では、サーバ証明書や暗号スイートについても細かい要件が定義されている。

https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html

* TLS 1.2
* 暗号スイートのforward secrecy対応
* サーバー証明書の著名アルゴリズム, 公開鍵のbit数

など. (CocoaKeys「Requirements for Connecting Using ATS」の項を参照.)

OSX El Captainで使えるnscurlを用いたサーバ側設定の確認方法については「Using the nscurl tool to diagnose ATS Connection Issues」の項を参照.

```
nscurl --ats-diagnostics https://twitter.com
```

とかで、とりあえず全てのテストでpassしていればO.K.

## 詳細なサーバ設定の確認

もうちょっと細かくサーバ設定を確認していきたい場合使うコマンドをメモっておく.

### cipherscan

https://github.com/jvehent/cipherscan

FQDNを与えるだけで、対応している暗号スイート、TLS設定等を一覧表示してくれる.

```bash

$./cipherscan twitter.com
.......................
Target: twitter.com:443

prio  ciphersuite                  protocols              pfs                 curves
1     ECDHE-RSA-AES128-GCM-SHA256  TLSv1.2                ECDH,P-256,256bits  prime256v1
2     ECDHE-RSA-AES128-SHA256      TLSv1.2                ECDH,P-256,256bits  prime256v1
3     ECDHE-RSA-AES128-SHA         TLSv1,TLSv1.1,TLSv1.2  ECDH,P-256,256bits  prime256v1
4     ECDHE-RSA-AES256-GCM-SHA384  TLSv1.2                ECDH,P-256,256bits  prime256v1
5     ECDHE-RSA-AES256-SHA384      TLSv1.2                ECDH,P-256,256bits  prime256v1
6     ECDHE-RSA-AES256-SHA         TLSv1,TLSv1.1,TLSv1.2  ECDH,P-256,256bits  prime256v1
7     AES128-GCM-SHA256            TLSv1.2                None                None
8     AES128-SHA256                TLSv1.2                None                None
9     AES128-SHA                   TLSv1,TLSv1.1,TLSv1.2  None                None
10    AES256-GCM-SHA384            TLSv1.2                None                None
11    AES256-SHA256                TLSv1.2                None                None
12    AES256-SHA                   TLSv1,TLSv1.1,TLSv1.2  None                None
13    ECDHE-RSA-DES-CBC3-SHA       TLSv1,TLSv1.1,TLSv1.2  ECDH,P-256,256bits  prime256v1
14    DES-CBC3-SHA                 TLSv1,TLSv1.1,TLSv1.2  None                None

Certificate: trusted, 2048 bits, sha256WithRSAEncryption signature
TLS ticket lifetime hint: 129600
OCSP stapling: not supported
Cipher ordering: server
Curves ordering: server - fallback: no
Server supports secure renegotiation
Server supported compression methods: NONE
TLS Tolerance: yes

```

最初に対応している暗号スイートと優先度が列挙された後、その他のTLS周りの設定が表示される.

* Certificate: サーバ証明書の著名アルゴリズムと公開鍵bit数
* TLS ticket lifetime hint : TLS Ticketを発行している場合、そのlifetime. 発行していない場合はnone.
  * TLS ticketはTLSセッション再開に使われる。TLSセッション再開は同一クライアントとの間の通信で、ハンドシェイクした情報を使い回すことで余計なclient <-> server間のround tripを削減できる.
* OCSP stapling
  * サーバ証明書が失効しているかどうかを高速に確認する設定.

### rfc5077-client

https://github.com/vincentbernat/rfc5077

* TLSセッション再開周りの設定を確認できる

### openssl

細かい設定を確認したい場合はopensslを使う. 証明書チェーンや、証明書本体、通信に利用する共通鍵、TLS Sessin Ticketなども確認できる。

```bash
o$penssl s_client -connect twitter.com:443

```

出力の-----BEGIN CERTIFICATE----- -----END CERTIFICATE-----の間が、実際の証明書なのでこれをtwitter.certなどという名前のファイルに保存して、以下のコマンドで証明書の中身も確認できる. 

```bash 
$openssl x509 -text -in twitter.cert

```

公開鍵2048bit, sha256WithRSAEncryptionであることが分かる。


## 関連する話題

調べていて、今後のHTTPSについて気になった話題をいくつかメモ.

* AWSのサーバ証明書サービス
  * http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs_manage.html

* HTTP2時代にhttpsをどこで終端させるか？という話
  * http://jxck.hatenablog.com/entry/http2-server-side-architecture

* TLSのSession再開に就て
  * http://techblog.yahoo.co.jp/infrastructure/ssl-session-resumption/