晴耕雨読

work in the field in fine weather and stay at home reading when it is wet

WPA3 の規格と脆弱性

WPA3 は WPA2 の脆弱性が指摘されたためリリースされた暗号化方式です。 WPA3の変更点としては主に3つあります。

  1. 鍵交換プロトコルがSAEになり、オフライン辞書攻撃に強くなった。
  2. SAEにより前方秘匿性が実現されたので、パスワードが漏れても過去の暗号通信は解読されない。
  3. WPA3-Enterpriseでは暗号化アルゴリズムがCNSA準拠になる。

SAE

SAE (Simultaneous Authentication of Equals) とは、パスワードに基づく認証および鍵交換プロトコルです。 SAE は RFC 7664 の Dragonfly 鍵交換プロトコルの派生で、Diffie-Hellman鍵交換プロトコルに基づくものです。 Diffie-Hellman鍵交換では認証ができない(中間者攻撃ができる)点が問題でしたが、Dragonfly鍵交換では事前共有鍵(パスワード)とMACアドレスから共有鍵を導出するので、鍵交換と認証を同時に行うこと (同等性同時認証; SAE) ができます。

WPA2

WPA2は4-way handshakeを行い、そこで事前共有鍵の導出と通信相手の認証を行います。

     Client                       Access Point
       |                                |
       |<---------Beacons(RSNE)---------|
  [Select cipher]                       |
       |-------AssocReq(RSNE-Chosen)--->|
       |<------AssociationResponse------|
       |                                |
       |                                |
       |<------------ANonce-------------|             ^
  [Derive PTK]                          |             |
       |----------(SNonce,MIC)--------->|             |WPA2
       |                           [Derive PTK]       |4-way handshake
       |                           [Verify RSNE]      |
       |<----------(MIC,GTK)------------|             |
  [Verify RSNE]                         |             |
       |--------------MIC-------------->|             V
       |                                |

WPA3

WPA3ではWPA2の4-way handshakeを行う前にSAEのハンドシェイクを行います。

     Client                       Access Point
       |                                |
       |<---------Beacons(RSNE)---------|
  [Select cipher]                       |
       |                                |
       |----Auth-Commit(scal1,elem1)--->|             ^
       |<---Auth-Commit(scal2,elem2)----|             |
  [Derive PMK]                     [Derive PMK]       |WPA3
       |-------Auth-Confirm(conf1)----->|             |SAE handshake
       |<------Auth-Confirm(conf2)------|             |(Dragonfly KEX)
  [Verify Conf]                    [Verif Conf]       V
       |                                |
       |                                |
       |-------AssocReq(RSNE-Chosen)--->|
       |<------AssociationResponse------|
       |                                |
       |                                |
       |<------------ANonce-------------|             ^
  [Derive PTK]                          |             |
       |----------(SNonce,MIC)--------->|             |WPA2
       |                           [Derive PTK]       |4-way handshake
       |                           [Verify RSNE]      |
       |<----------(MIC,GTK)------------|             |
  [Verify RSNE]                         |             |
       |--------------MIC-------------->|             V
       |                                |

SAE handshakeによってパスワードとMACアドレスと乱数を使って鍵共有を行います。 その結果、通信毎に異なるセッション鍵を生成するようになり、前方秘匿性を実現します。 また、SAEをすることによって弱いパスワードが強いパスワードになるので(KDFなどによってエントロピーが高くなるので)、より安全な暗号化通信を行うことができます。

もしクライアントはWPA3に対応していなくても、従来のWPA2の通信で始めることができるので、WPA3はWPA2と互換性があります。

Dragonfly Key Exchange

WPA3ではSAEハンドシェイクとしてDrangonfly鍵共有(Dragonfly KEX)を行います。 Dragonflyでは次の手順で鍵共有を行います1

  1. 事前共有鍵(passwd)と両者のMACアドレス(AとB)から生成元(P)を選びます。 生成元を求めるアルゴリズムは「Hunting and Pecking」と言います。
  2. 乱数を2つ生成し、それぞれを秘密鍵(rA)とマスク(mA)とします。
  3. 秘密鍵とマスクから、スカラ(sA)と、マスク(mA)でスカラ倍した元(EA)を作ります。
  4. Auth-Commitで、AliceとBobで互いのスカラと元を共有します。
  5. 共有した情報から自分の秘密鍵(rA)でスカラー倍した元(K)が共有鍵となります。
  6. Auth-Confirmで、トランザクションを共有鍵でハッシュ化した値を共有します。
  7. ハッシュ値が計算した結果と一致すれば、正しく共有鍵を導出できたことが確認できます。
    Alice (e.g. a client)                  Bob (e.g. an AP)
      |                                      |
  [P = GenPE(passwd,A,B)]                [P = GenPE(passwd,A,B)]
  [Pick random rA and mA]                [Pick random rB and mB]
  [sA = (rA + mA) mod q ]                [sB = (rB + mB) mod q ]
  [EA = -mA * P         ]                [EB = -mB * P         ]
      |                                      |
      |------------Auth-Commit(sA,EA)------->|
      |<-----------Auth-Commit(sB,EB)--------|
      |                                      |
  [Verify sB and EB      ]               [Verify sA and EA      ]
  [K = rA * (sB * P + EB)]               [K = rB * (sA * P + EA)]
  [tr = (sA, EA, sB, EB) ]               [tr = (sB, EB, sA, EA) ]
  [cA = HMAC(HASH(K), tr)]               [cB = HMAC(HASH(K), tr)]
      |                                      |
      |------------Auth-Confirm(cA)--------->|
      |<-----------Auth-Confirm(cB)----------|
      |                                      |
  [Verify cB]                            [Verify cA]
      |                                      |

Dragonfly鍵交換では有限体上の演算か、有限体上の楕円曲線上の演算かを選ぶことができますが、安全性と通信効率を考えて、ここでは楕円曲線上の演算を前提としています。 楕円曲線上の点(P)のスカラ倍(rA * P)を求めるのは簡単ですが、その逆演算は難しいという離散対数問題を利用している暗号技術です。

Hunting and Pecking アルゴリズム

Hunting and Pecking はパスワードと通信する両者のMACアドレスから生成元 $g$ を導出するアルゴリズムです。Diffie-Hellman鍵共有では、生成元は既にパラメータとして与えられているものを使いますが、SAEでは毎回異なる生成元 $g$ を使います。

def hunting_and_pecking(password, alice, bob):
  found, counter = False, 0
  k = 40
  while counter < k or not found:
    base = Hash(max(alice,box), min(alice,bob), password, counter)
    temp = KDF(base, "Dragonfly Hunting and Pecking")
    seed = (temp % (p - 1)) + 1
    if is_quadratic_residue(seed^3 + a * seed + b, p):
      if not found:
        x, save, found = seed, base, True
    counter += 1

  y = sqrt(x^3 + a * x + b) mod p
  P = (x, y) if LSB(save) == LSB(y) else (x, p - y)
  return P

このアルゴリズムの中では平方剰余かを調べる関数 is_quadratic_residue が使われていますが、一般的な方法で平方剰余かを調べると、アルゴリズムの終了時間から秘密鍵となる生成元Pのx座標を推測することが可能になります。 そこでブラインド値を使って平方剰余かを調べる関数を作る必要があります。

脆弱性

Hunting and Pecking では有限体上の楕円曲線上の生成元を求めていますが、必ず40回試行をした上で生成元を決定します。ハッシュ化した値が有限体上の楕円曲線上の点であったときにループを終了させると、アルゴリズムの終了時間に差が出てしまうためです。 RFCがDraftの段階では is_quadratic_residue がサイドチャネル攻撃に弱いというと指摘がありましたが、現在はブラインド値を使う方法に修正されています2

Hunting and Pecking への攻撃として、その処理の重さを利用して、大量(70件以上)の接続リクエストを出すことでルータのCPU使用率を100%近くにするDoS攻撃などもあります2

Chosen Random Value Attack (選択乱数攻撃) ではアクセスポイントAPが生成する乱数(rB)を0に固定することで、事前共有鍵を知らなくても確率1/qで通信を復号することができる攻撃もあります。 具体的には攻撃者のAP側が乱数 rB = 0 を固定し、クライアント側がマスク mA = 1 となったときに成功するので、実装の対策としては乱数を生成するときに範囲を [1,q) ではなく [2,q) にすれば安全になります3

CNSA

CNSA (Commercial National Security Algorithm) とは NSA (国家安全保障局) が定めた暗号スイートのことです4。 WPA3の暗号アルゴリズムはCNSAに準拠するらしいので、例えば Hunting and Pecking で使う楕円曲線のパラメータは P-384 (secp384r1) のものを使うことになると思います。 以下に CNSA で定められている暗号スイートでWPA3(-Enterprise?)で使う一覧を示します5

Algorithm Function Specification Parameters
AES Symmetric block cipher used for information protection FIPS Pub 197 Use 256 bit keys
ECDH Key Exchange Asymmetric algorithm used for key establishment NIST SP 800-56A Use Curve P-384
SHA Algorithm used for computing a condensed representation of information FIPS Pub 180-4 Use SHA-384
DH Key Exchange Asymmetric algorithm used for key establishment IETF RFC 3526 Minimum 3072-bit modulus

付録

Wi-Fi がこれまで使ってきた認証と暗号化の方法の一覧を以下に示します6

Standard WEP WPA WPA2 WPA3
Release 1997 2003 2004 2018
Encryption RC4 TKIP with RC4 AES-CCMP AES-CCMP & AES-GCMP
Key Size(s) 64-bit and 128 128-bit 128-bit 128 and 256 bit
Cipher Type Stream Stream Block Block
Authentication Open System & Shared Key PSK & 802.1x with EAP variant PSK & 802.1x with EAP variant SAE & 802.1x with EAP variant

その他の関連資料


参考文献