TOPへ戻る

メッセージ認証コード

  • データの完全性を保護する暗号プリミティブとしてMessage Authentication Code(MAC)が得られる(定義できる?)。
    • ハッシュ関数と秘密鍵を組み合わせることで定義される
  • 秘密鍵の導入はどんなセキュリティでも基本的なもん。
    • 鍵がないと機密性を保証できず、認証も出来ないため。
    • ハッシュ関数は任意のデータについて真正性・完全性を保証する。
      • 裏では改ざんが出来ない、信頼性の高い「経路」の存在が大きい。
  • MACを使用して信頼性の高い経路を設けることや、MACで実現できる機能をさらう。

3.1 ステートレスCookie、MACの導入となる例

  • 自分がWebページであると想像しよう(!?)
    • いろいろなユーザが集まってくる
    • Webページである自分と対話(通信)するには、ログインに必要な資格情報(Credentials)を送ってもらい、検証する必要がある。最初の登録情報と一致すれば、ユーザの認証ができることになる
  • Cookieは、何度も同じリクエストが発生することが想定される場合、都度認証を繰り返さずに済むように、ユーザの資格情報をブラウザに保存して、リクエストのたびに自動送信する。
    • Cookieは資格情報に限らず、ユーザに送信してほしい内容をなんでも保存できる。
    • セッションごとのCookieは、ユーザログイン直後に生成されるランダムな文字列を保持して、パスワードなどの秘密情報を平文で保存しないようにしている。
    • Cookieが漏洩しても、ユーザのパスワードに関する情報はもれない
      • ただし、攻撃者はユーザになりすます事ができる。
  • サーバが増えた場合、ユーザとランダムな文字列の対応をすべてのサーバで共有するのは面倒(だし危険?)
    • ブラウザ側で保存する情報を増やすことで対応できる。
      • Cookieにランダムな文字列を保存せず、代わりにユーザ名を保存する
        • 平文で保存されると、ユーザ名の改ざんでなりすましができてしまう
        • ユーザ名をハッシュ化すると、改ざんした結果とハッシュ値が対応しなくなることが期待できるので、有効な手になりうる。
      • ユーザ名だけではなく、そのダイジェストもCookieに保存したい。
        • ハッシュの元を信頼できない場合、データの完全性は保証されない。
        • たとえばbob|hash(bob)というCookieを得られた場合、ハッシュ関数は公開されているので、eve|hash(eve)としてサーバへリクエストができてしまう。
    • MACはこうしたアプローチに対して良い答えを与えそう。
  • MACは入力と秘密鍵をとる秘密鍵アルゴリズム
    • 入力と秘密鍵を使って認証タグを返す関数と考える。
    • 図3.3をプログラムにすると以下。
auth_tag = MAC(x, secretkey) # MAC function is blackbox.
  • 秘密鍵がないと、認証タグは生成出来ない。

  • Cookieの改ざんを防ぐためにMACを使ってみる。

    • ブラウザ「username: bob, pass:hunter2
      • 自分(Webサイト)「Cookie: bob|mac(k, bob)
    • 悪意のある人「eve|hogehoge
      • 自分(Webサイト)「認証タグが不正」
  • 秘密鍵をもっている人でないと計算できない店で、プライベートなハッシュ関数に近い理解ができる。

    • ハッシュ関数からMACが作られることもある。

3.2 コードで見る実際の例

  • MACを使う人が複数になった場合を想定してコードを書いてみる。
    • 誰かと連絡を取りたいが、とりあえずメッセージを読まれても良い。
    • ただし、メッセージの改ざんは防ぎたい。
  • メッセージを送り合う2者が同じ秘密鍵を使って、メッセージの完全性を保護する。
  • Hash-based MACは、コア部分でハッシュ関数を利用するMAC
    • SHA-2で実装されることが多い RustでHMACを考える。

送信側

use sha2::Sha256;
use hmac::{Hmac, Mac, NewMac};

// u8: Rustのデータ型で符号なし整数(数字はポインタのサイズ)
fn send_message(key: &[u8], message: &[u8]) -> Vec<u8> {
    // 秘密鍵とSHA-256ハッシュ関数でHMACを初期化する。
    let mut mac = Hmac::<Sha256>::new(key.into());

    // HMACへの追加入力をバッファに入れる
    mac.update(message);

    // 認証タグを返す
    mac.finalize().into_bytes().to_vec();
} 

受信側

メッセージと認証タグをもらったら、受信側は同じ秘密鍵を使ってタグ生成を行い、
認証タグと比較すれば結果が返ってくる。

use sha2::Sha256;
use hmac::{Hmac, Mac, NewMac};

fn receive_message(key: &[u8], message: &[u8],
    authentiacion_tag: &[u8]) -> bool {
        // 同じ秘密鍵とメッセージから認証タグを再生成する
        let mut mac = Hmac::<Sha256>::new(key);

        // 再生性された認証タグが、受診したタグと一致するかを確認する
        mac.verify(&authentiacion_tag).is_ok();
    }

注意: リプレイが可能であるから完全ではない。

メッセージと認証タグをリプレイすること自体も真正性が維持されるし、
再送信されたメッセージかどうかを確認する方法がない。

3.3 MACのセキュリティ特性

MACにも難点・落とし穴が存在するが、そのためにはMACのセキュリティ特性と正しい利用場面を確認する必要がある MACの特徴は以下。

  • 認証タグの捏造に強い
  • 安全性を確保するには、認証タグの長さは最小限でなければならない
  • 認証方法が単純だとメッセージのリプレイが可能になる
  • 認証タグの検証がバグりやすい

3.3.1 認証タグの捏造

仮に攻撃者が、任意のメッセージに対する認証タグを大量に生成するようリクエストできたとしても、
MACは(それ以前に)見たことのないメッセージに対する認証タグを捏造できないという点が保証される。
(よくわからん。)

MACに使用する秘密鍵が秘匿されている限りは、こうした捏造から保護される。
そのためには秘密鍵が十分にランダムで、十分に大きくなっている(16バイト)必要がある。

  • MACは「曖昧さを狙った攻撃」に弱い
    • 構造を持ったメッセージを認証する場合、認証の前にシリアライズする必要がある。

説明

  • 任意のメッセージ\(m\)に対して、認証タグ\(t = MAC(k, m)\)を生成した事を考える。
    • このとき、\(k\)を知ることなしに認証タグを計算することが出来ない。
  • 上記の理論的な安全性を保っているので最高だが、MACはそれ以上に強い性質。
    • 制約のあるメッセージに対する認証タグの取得を攻撃者に許す場面が多い。
      • Cookieで利用可能なニックネームを登録したら、任意の認証タグが得られる

攻撃者が任意のメッセージに対する認証タグをリクエストできたとしたら、そもそも何を保護できるというのだろうか。 だが、暗号学におけるセキュリティの証明とはこういうものなのだ。実際には、攻撃者がここまで強力であることは少ないので、有能な攻撃者でさえ不正を行えないとすれば、それより非力な攻撃者には、まず手が打てないことになるからだ。

3.3.2 認証タグの長さ

MACを使っている場合、衝突攻撃が考えられる。

MACの衝突を考える場合、入力\(x\)\(y\)に対して、
\(MAC(k, x) = MAC(k, y)\)が満たされる場合を衝突と定義する。

【復習】ハッシュ関数の衝突
\(HASH(x) = HASH(y)\)となるような入力\(x\)\(y\)を見つける

誕生日限界を思い出すと、アルゴリズムの出力が大きくない場合、
衝突が見つかる期待は高まってしまう。

例: 64ビットの認証タグを生成するサービスに対する衝突は\(2^{32}\)回のリクエストでOK。

衝突攻撃に対して頑健であるために、128ビットを要請する。
\(2^{64}\)の認証タグリクエストは、秘密鍵を固定して、1Gbsのリンクでも25万年。
実際は秘密鍵も変更するので、まあ数十万年から数百万年かかる。

MACは秘密鍵を持つ関数であるので、オフラインでの最適化が難しい。
(ハッシュ関数はアルゴリズムが公開されているので、インターネットがなくても計算ができる)
攻撃側は認証タグをサーバにリクエストするしかないので、MACを攻撃するには
相当に時間がかかる。

3.3.3 リプレイ攻撃

3.3.4 一定時間で認証タグを検証する

3.4 現実世界のMAC

3.4.1 メッセージの認証

3.4.2 鍵の導出

3.4.3 Cookieの完全性

3.4.4 ハッシュテーブル

3.5 メッセージ認証コード(MAC)の実際

3.5.1 HMAC: ハッシュベースのMAC

3.5.2 KMAC: cSHAKEベースのMAC

3.6 SHA-2と伸長攻撃