メッセージ認証コード ~ MAC / HMAC ~

■ はじめに

仕事で、HMACなるものがでてきたので調べてみた。
軽く書いて終わらせるつもりだったが、
内容がかなりの量になり、かつ、勉強になった。

目次

【1】MAC
 1)入力値
 2)MACを使った認証の流れ
 3)一方向ハッシュ関数との違い
【2】HMAC
【3】セキュリティ攻撃
 1)再生攻撃・リプレイ攻撃
 2)秘密鍵推測する攻撃
【4】制限事項(解決できない事項)
 1)第三者に対する証明
 2)否認防止

【1】MAC

* MAC = Message Authentication Code (メッセージ認証コード)
* 正真性を確認し、メッセージの認証を行う技術

正真性 (integrity)とは?

* そのデータが正真正銘、本物であるという性質
 => はじめ、「せいしんせい」と読んでいたが、「しょうしんせい」だった
* 「完全性」とも呼ぶ

cf integrity

https://eow.alc.co.jp/search?q=integrity

より抜粋
~~~~
1. 誠実、正直、高潔、品位
2. 完全(な状態)、完全性、全体性
3. インテグリティ◆システムや信号の整合性を意味する。
~~~~

1)入力値

[1] 任意長のメッセージ(受信者に送りたいメッセージ)
[2] 共通鍵(送信者・受信者が共有する鍵)
 => この2つの入力値を元に固定長の出力値(MAC値という)を算出する

2)MACを使った認証の流れ

* 以下のサイトの図が分かりやすい

https://atmarkit.itmedia.co.jp/ait/articles/0401/01/news120.html

3)一方向ハッシュ関数との違い

* 一方向ハッシュ関数では、「[2] 共通鍵」は使用しない
 => 送信者・受信者以外のものに改ざんされても、
  「共通鍵」を知らないとMAC値を算出できないので
  正真性を確かめることができる(漏れたらOUTだけど)

【2】HMAC

* HMAC = Hash-based MAC
* 任意の一方向ハッシュ関数を用いてMAC値を生成するアルゴリズム

※「任意の一方向ハッシュ関数」について

* 「任意」とあるのは、一種類に定められていないため。
 + SHA-1 を使えば、HMAC-SHA1
 + MD5 を使えば、HMAC-MD5
 + RIPEMD-160 を使えば、HMAC-RIPEMD

【3】セキュリティ攻撃

1)再生攻撃・リプレイ攻撃

* めちゃくちゃ勉強になった、、、

例:銀行の入金システム

[1] AさんがB銀行に100万円を入金したとする
 => MAC値を計算し、この入金を受け付ける
[2] [1] のデータをハッカー X が盗聴し、入金およびMAC値を保存
[3] ハッカー X は、[2] のデータを100回繰り返す
 =>すると、100万円×100回で1億円入金できてしまう

対応方法1:シーケンス番号

* 通信する際に毎回シーケンス番号を振り、
 MAC値を計算する際には、
 このシーケンス番号もメッセージに含めるようにする
 => シーケンス番号を知らないと、100回繰り返しても
  MAC値が異なり、認証ができない
* 【条件】実装する際は、通信相手ごとに
 最後のシーケンス番号を記録しておく必要がある

対応方法2:タイムスタンプ

* 送信時刻を埋め込むようにする
 => ただし、通信速度などの時間差があるので、攻撃の余地が残る
* 【条件】送信者と受信者で時刻を一致させておく必要がある

対応方法3:使い捨てランダム値(ノンス; Nonse)

* 受信者から送信者に対して使い捨てのランダム値(ノンスと呼ぶ)を渡し、
 そのノンスを使って、MAC値を算出する
 => ただし、通信量が多少増える

cf. Nonse = number used once の略 (=一度だけ使われる数)

2)秘密鍵推測する攻撃

* 総当たり攻撃(ブルート・フォース・アタック; brute force attack)や
 誕生日攻撃などにより秘密鍵を推測してしまう攻撃
 => 秘密鍵は推測されない、かつ、十分な桁数のものにしなくてはならない

【4】制限事項(解決できない事項)

https://atmarkit.itmedia.co.jp/ait/articles/0401/01/news120.html

の「注意点」を参照。
 => MACはあくまで『メッセージの「完全性だけ」を保証』するだけのもの

1)第三者に対する証明

* 送信者・受信者以外の第三者に対して、
 「このメッセージは、送信者から送られてきたもの」という証明は
 MACでは証明することはできない
 => 秘密鍵は受信者も知っているので、受信者から送られてきたかもしれない
 => 第三者に秘密鍵を教えなくてはならない

2)否認防止

* 送信者は受信者に対して
 「そのメッセージを送っていない」と否認することも可能
 
cf. 否認(repudiation)

関連記事

ハッシュ / Hash
https://dk521123.hatenablog.com/entry/2022/09/14/000000
Python ~ ハッシュ ~
https://dk521123.hatenablog.com/entry/2020/05/03/010502
Python ~ HMAC ~
https://dk521123.hatenablog.com/entry/2022/10/08/002750
Java でEmail を送るには ~ SMTP認証 / DIGEST-MD5 編 ~
https://dk521123.hatenablog.com/entry/2016/12/07/222229