メッセージ認証コードでなりすましを防ぐ
皆さん、こんにちは。技術開発グループのn-ozawanです。
昨日はハロウィンでしたね。皆さんは仮装しましたか?私はカボチャを食べました。
本題です。
以前、ハッシュ関数の概要についてお話ししたときに、ハッシュ関数の問題点としてなりすましを挙げました。今回はハッシュ関数のなりすましを防止する方法としてメッセージ認証コードを取り上げたいと思います。
目次
メッセージ認証コード
概要
メッセージ認証コードは、ハッシュ関数の問題点であるなりすましを防止します。アリスとボブには予め二人だけの秘密である共通鍵を共有します。そして、送信元であるアリスは、メッセージと共通鍵を用いてメッセージ認証コードを行いMAC値を得ます。アリスはボブに、メッセージとMAC値を送信します。
ボブはアリスから受け取ったメッセージと共通鍵でMAC値を得ます。アリスから受け取ったMAC値と自分が得たMAC値を比較することで改竄およびなりすましがないことを確認します。
もし攻撃者マロニーが悪さをしようとしても、アリスとボブが秘密にしている共通鍵を入手しない限りは、なりすますことが出来ません。

メッセージ認証コードの現在
CRYPTRECが公表している電子政府における調達のために参照すべき暗号のリストでは、HMACとCMACが推奨されています。一方、SSL/TLSでは、1.2まではHMACに対応していたものの、1.3からは非対応となりました。これはHMACに問題があった訳ではなく、TLS 1.3以降からは共通鍵暗号時にGCMモードなどの認証付き暗号を行っており、メッセージ認証コードを利用する必要性がなくなったためだと思われます。
HMAC
HMACはハッシュ関数を利用したメッセージ認証コードです。RFC 2104で公開されています。HMACで利用するハッシュ関数は、任意の繰返し型ハッシュ関数であれば利用可能とされており、SHA-1やSHA-2、SHA-3、MD5などが利用可能です。もし、HMACでSHA-256を利用する場合は、HAMC-SHA256と呼びます。
HMACで得られるMAC値の長さはハッシュ関数に依存します。もし、SHA-256を利用したのであれば、MAC値は256bitになります。また、共通鍵の長さもハッシュ関数に依存します。HMACでは共通鍵の長さはLバイト以上、Bバイト以下が望ましいと言われています。
「Lバイト」というのは、ハッシュ関数が出力するハッシュ値の長さです。「Bバイト」というのは、ハッシュ関数のブロックの長さです。例えばSHA-256であれば、共通鍵は32バイト以上、64バイト以下が望ましい、ということになります。
HMACの処理フロー
HMACの処理フローは以下の通りです。
- 共通鍵をBバイトの長さになるように0でパディングします。
- パディング済み共通鍵と、ipad (0x36をBバイト分繰り返した値) とXORします。
- XORした結果とメッセージを結合し、ハッシュ関数を実行します。
- パディング済み共通鍵と、opad (0x5CをBバイト分繰り返した値) とXORします。
- XORした結果と、ステップ3で得た結果を結合し、ハッシュ関数を実行します。
- 実行した結果がMAC値となります。

メッセージ認証コードの問題点
メッセージ認証コードは、共通鍵を秘密にすることにより、なりすましを防止します。しかし、どうやって共通鍵を秘密に共有するのか、共通鍵暗号方式と同じ問題を抱えています。
また、共通鍵の問題以外にも、メッセージ認証コードは否認防止がない問題もあります。もし、アリスがボブへデータを送信した後、アリスが「ボブにメッセージを送信していない」と、自分が送信したことを否認したとします。もちろんモブはアリスからメッセージを受け取っています。MAC値もあります。ボブが「いやいや、アリスから確かにメッセージを受け取ったよ」と主張しても、それを立証することが出来ません。なぜなら、アリスとボブ以外、共通鍵を共有した経緯を知りませんし、アリスが共通鍵を破棄してしまえば、誰も客観的な検証が出来なくなるからです。
おわりに
暗号技術の分野では、相手にデータを読まれないようにする「機密性」、データが改ざんされていないことを保証する「完全性」、意図した相手からデータを受け取る「真正性」、そしてしっかりと証拠を残して相手が否認することを防止する「否認防止」が必要になります。この「否認防止」を解決するにはデジタル署名があります。次回はデジタル署名についてお話ししたいと思います。
余談ですが、RFC2104ってoctetではなくbyteなんですね。RFCの仕様を多く読んだ訳ではないのですが、byteを用いるのは初めて見ました。何か理由があるんですかね?
ではまた。