コンパクトTLS (cTLS)


1. はじめに

TLS(Transport Layer Security)のセキュリティプロトコルの仕様としての課題はTLS1.3でかなりのところ整理されました。それでもいくつかの点ではさらに検討が進められています。コンパクトTLS(cTLS)もその一つです。cTLSはTLS1.3[RFC8446]プロトコルの軽量化を目指すプロトコル仕様で、2019年から検討が進められています。RFCとなるにはまだ時間がかかると思われるものの、2022年3月現在ドラフト5が公開されていて、その骨格を知ることができます。以下、その内容について紹介します。

2. コンパクト化の方針、目標

cTLSはTLSに残されている後方互換性のためのフィールドなどを排除し、楕円曲線の点圧縮などのコンパクトエンコーディング以上の軽量化を目指します。テンプレートベースの特殊化(後述)を利用することで、ネゴシエーションによらずに通信の両者で必要な情報を共有させます。また、準静的ディフィーヘルマンのような新しい暗号技術を取り入れます。

これらによって、使用する証明書が事前に確定している場合(EC)DHEハンドシェークで原理的に必要な最小限の暗号情報サイズに対して45バイトのオーバーヘッド、PSKハンドシェークの場合、21バイトのオーバヘッドでハンドシェークを完了します。

3. テンプレートベースの特殊化

TLSは、証明書ベースの認証、生の公開鍵ベースの認証、また事前共有鍵(PSK)ベースの認証などさまざまなスキームを通信相手とのネゴシエーションで決定することができるようになっています。この完全に汎用的なものから、ある自由度を削除してみます。例えば、TLSの1つのバージョンのみをサポートする場合には、バージョンネゴシエーションは不要となり、supported_version拡張を省略することができます。この特殊化されたハンドシェークはワイヤーエンコーディング(ネットワークの物理層に送信される情報)のみに適用されるもので、その内容は同じ機能が使用されたTLS1.3のハンドシェークの内容と等価になります。

特殊化は、ハンドシェイクとレコードレイヤーの間のステートフルな圧縮レイヤーとして見ることができます(下図)。

JSON記述された圧縮プロファイルでテンプレートの仕様を規定します。プロファイルでは、アルゴリズム、アルゴリズムパラメータ、また拡張機能の仕様などを定義します。クライアントは使用したいプロファイルをClientHelloのプロファイルフィールドでサーバに通知します。

例えば、固定バージョン(TLS 1.3)と固定暗号スイート(TLS_AES_128_GCM_SHA256)を使用するプロトコルについて説明します。回線上では、ClientHello.cipher_suites、ServerHello.cipher_suitesとClientHelloとServerHelloのsupported_versions拡張機能は省略されます。

   {
      "version" : 772,
      "cipherSuite" : "TLS_AES_128_GCM_SHA256"
   }

これにより次の要素が定義されます。

  • プロファイル(整数):プロファイルのID。
  • version(integer):この場合、TLS1.3を示す772 == 0x0304
  • cipherSuite(文字列):[RFC8446]のセクション8.4で定義されている「TLS_AEAD_HASH」構文を使用。
  • dhGroup(文字列):鍵の確立に使用するDHグループを指定。[RFC8446]のセクション4.2.7mpコードポイント名。 (例:x25519)。
  • signatureAlgorithm(文字列):認証に使用する署名スキーム。[RFC8446]のセクション4.2.7にコードポイント名 (例:ed25519)。
  • random(integer):乱数長は32バイト以下
    . 相互認証(ブール値):trueに設定されている場合、クライアントが証明書とCertificateVerifyメッセージを送信して証明書で認証する。

4. 圧縮効果の例

圧縮効果の例として、証明書を使用した相互認証をサポートする完全なcTLSベースの交換を示します。 SHA256およびNISTP256r1でECDSA、Diffie-HellmanはFX25519曲線、スイートはTLS-AES-128-CCM8-SHA256です。 証明書は、既知の証明書のIDを使用して交換されます。

この例での圧縮効果を下のグラフに示します。

この例には次のプロファイルが使用されています。

   {
     "profile": 1,
     "version": 772,
     "cipherSuite": "TLS_AES_128_CCM_8_SHA256",
     "dhGroup": "X25519",
     "signatureAlgorithm": "ECDSA_P256_SHA256",
     "finishedSize": 8,
     "clientHelloExtensions": {
       "server_name": "000e00000b6578616d706c652e636f6d",
     },
     "certificateRequestExtensions": {
       "certificate_request_context": 0,
       "signature_algorithms": "00020403"
     },
     "mutualAuth": true,
     "extension-order": {
          "clientHelloExtensions": {
             Key_share
          },
          "ServerHelloExtensions": {
             Key_share
          },
     },

     "knownCertificates": {
       "61": "3082...",
       "62": "3082...",
       "63": "...",
       "64": "...",
       ...
     }
   }
   ClientHello: 36 bytes = DH(32) + Overhead(4)

   01                    // ClientHello
   01                    // Profile ID
   0020 a690...af948     // KeyShareEntry.key_exchange
   ServerHello: 36 = DH(32) + Overhead(4)

   02                 // ServerHello
   26                 // Extensions.length
   0020 9fbc...0f49   // KeyShareEntry.key_exchange
   Server Flight: 80 = SIG(64) + MAC(8) + CERTID(1) + Overhead(7)

EncryptedExtensions、およびCertificateRequestメッセージは空なので省略します。

   0b                 // Certificate
     03               //   CertificateList
       01             //     CertData.length
         61           //       CertData = 'a'
   0f                 // CertificateVerify
     4064             //   Signature.length
          3045...10ce //   Signature
   14                 // Finished
     bfc9d66715bb2b04 //   VerifyData
   Client Flight: 80 bytes = SIG(64) + MAC(8) + CERTID(1) + Overhead(7)
   0b                 // Certificate
     03               //   CertificateList
       01             //     CertData.length
         62           //       CertData = 'b'
   0f                 // CertificateVerify
     4064             //   Signature.length
          3045...f60e //   Signature
   14                 // Finished
     35e9c34eec2c5dc1 //   VerifyData