はじめに
API認証やWebhookの実装をしていると、HMACという言葉が出てきます。
この記事では、HMACが何をする仕組みなのかを整理します。
HMACは改ざん検知のための仕組み
HMACは Hash-based Message Authentication Code の略です。
簡単に言うと、
このデータが途中で書き換えられていないことを確認するための仕組み
です。
例えば、
注文金額: 1000円
というデータを送るとします。
受信した側は、
注文金額: 100000円
になっていないことを確認したいはずです。
HMACは、このような改ざんを検知するために利用されます。
ハッシュだけでは不十分
改ざん検知と聞くと、SHA-256などのハッシュ関数を思い浮かべるかもしれません。
例えば、
SHA256("hello")
を計算すると、決まったハッシュ値が得られます。
しかし、SHA-256だけでは問題があります。
誰でも同じ計算ができるためです。
つまり、
データを書き換える
↓
新しいSHA-256を計算する
↓
一緒に送る
ことができてしまいます。
受信側から見ると、本当に送信者が作ったものなのか判断できません。
秘密鍵を使う
そこでHMACでは秘密鍵を利用します。
イメージとしては、
データ
+
秘密鍵
↓
HMAC生成
です。
例えば、
message = "hello"
secret = "my-secret-key"
からHMACを計算します。
受信側も同じ秘密鍵を持っているため、同じ計算ができます。
もし途中でデータが変更されていれば、計算結果は一致しません。
何を保証しているのか
HMACが保証しているのは主に2つです。
まず、
データが改ざんされていない
ことです。
もうひとつは、
秘密鍵を知っている相手が作った
ということです。
秘密鍵を知らない第三者は正しいHMACを生成できません。
そのため、送信元の確認にも利用できます。
Webhookでよく使われる
HMACの利用例として分かりやすいのがWebhookです。
例えばGitHubやStripeからWebhookを受信する場合、
送信側はリクエスト本文からHMACを生成して署名を付与します。
受信側は、
受け取った本文
+
共有秘密鍵
からHMACを再計算します。
結果が一致すれば、
そのリクエストは正しい送信元が作成したものであり、途中で改ざんされていないと判断できます。
API認証でも利用される
HMACはAPI認証でも利用されています。
例えばAWSの署名付きリクエストでは、秘密鍵を利用してリクエストへ署名を付与します。
サーバー側はその署名を検証することで、
リクエストが正しい利用者によって作成されたことを確認します。
HMACは暗号化ではない
ここはよく誤解されるポイントです。
HMACはデータを隠す仕組みではありません。
例えば、
ユーザーID: 123
というデータがあった場合、
HMACを付与しても内容は見えます。
HMACがやっているのは、
見えるけど改ざんできないようにする
ことです。
データを隠したい場合は暗号化が必要になります。
HMAC-SHA256とは
実際のシステムでは、
HMAC-SHA256
のような表記を見かけます。
これは、
HMAC
+
SHA-256
を組み合わせているという意味です。
現在はHMAC-SHA256やHMAC-SHA512が広く利用されています。
おわりに
HMACは普段意識する機会は多くありませんが、API認証やWebhookなど様々な場所で利用されています。
実装時にはライブラリが計算してくれることも多いですが、何を検証しているのかを知っておくと、認証周りの仕組みを理解しやすくなります。