HMACとは?

HMAC(Hash-based Message Authentication Code)は、秘密鍵とハッシュ関数を組み合わせて一意の認証コードを生成する暗号化技術です。単純なハッシング処理とは異なり、HMACはデータの完全性と真正性の両方を保証します。メッセージが改ざんされていないことを検証し、送信者の身元を確認します。

HMACは、メッセージをハッシュ関数(SHA-256など)で2回処理し、秘密鍵を特定の方法で混ぜることで機能します。このダブルハッシング方式により、プレーンなハッシュ関数に影響する長さ拡張攻撃に対する耐性が得られます。

HMACはどのように機能しますか?

HMACアルゴリズムは、以下のステップに従います:

  1. 鍵の準備:秘密鍵がハッシュブロックサイズより長い場合、まずハッシュされます。短い場合は、ゼロでパディングされます。
  2. 内部ハッシュ:鍵が内部パディング定数(ipad)とXOR演算され、メッセージと連結されてハッシュされます。
  3. 外部ハッシュ:鍵が外部パディング定数(opad)とXOR演算され、内部ハッシュ結果と連結されて再度ハッシュされます。

数式は以下の通りです:HMAC(K, m) = H((K ⊕ opad) || H((K ⊕ ipad) || m))

この構造により、攻撃者がメッセージのハッシュを知っていても、秘密鍵を知らなければ有効なHMACを偽造できません。

通常のハッシング処理の代わりにHMACを使用する理由は?

機能 通常のハッシュ HMAC
データの完全性
認証
秘密鍵が必要
長さ拡張攻撃からの保護
API認証に適している

通常のハッシュ(MD5、SHA-256)はデータが変更されていないことのみを検証します。HMACは、メッセージが秘密鍵を知っている人から送信されたことを追加で証明するため、安全な通信に不可欠です。

ハッシュアルゴリズムの理解

アルゴリズム 出力サイズ セキュリティレベル パフォーマンス 推奨事項
SHA-1 160ビット(40文字の16進数) 弱い 最速 レガシーシステムのみ
SHA-256 256ビット(64文字の16進数) 強い 高速 推奨デフォルト
SHA-384 384ビット(96文字の16進数) 非常に強い 中程度 高セキュリティが必要な場合
SHA-512 512ビット(128文字の16進数) 非常に強い 中程度 最大セキュリティ

SHA-256は、ほとんどのアプリケーションでセキュリティとパフォーマンスの最適なバランスを提供します。SHA-1は従来のシステムとの互換性のために含まれていますが、既知の脆弱性があるため、新しい実装では避けるべきです。

出力形式の比較

16進数:文字0~9とa~fを使用します。より長い文字列を生成しますが、読みやすくデバッグしやすいです。APIとログで一般的です。

Base64:文字A~Z、a~z、0~9、+、/を使用します。より短い文字列を生成します(16進数より約33%短い)。JWTトークンとコンパクトなデータ送信で一般的です。

同じHMACの例:

  • 16進数:5d5d139563c95b5967b9bd9a8c9b8c8d8e8f9a9b9c9d9e9f0a0b0c0d0e0f1011
  • Base64:XV0TlWPJW1lnub2ajJuMjY6Pmpm9nZ6fCgsMDQ4PEQ==

ツール説明

このHMACジェネレータは、Web Crypto APIを使用して暗号化認証コードを作成し、安全なクライアント側の計算を実現します。メッセージと秘密鍵を入力して、ハッシュアルゴリズム(SHA-1、SHA-256、SHA-384、またはSHA-512)と出力形式(16進数またはBase64)を選択して、HMAC署名を即座に生成します。

すべての処理はブラウザ内で完全に実行されます。秘密鍵とメッセージはサーバーに送信されないため、完全なプライバシーとセキュリティが保証されます。

例1:APIリクエスト署名

  • メッセージ:GET /api/users?timestamp=1704067200
  • 秘密鍵:my-api-secret-key-2024
  • アルゴリズム:SHA-256
  • 出力(16進数):d090e24b18ee077bdeceacab17fb15ff8cf7868147b302dbcb1b11630465e817

機能

  • 複数のハッシュアルゴリズム:SHA-1、SHA-256、SHA-384、SHA-512をサポートし、ビット強度を示すビジュアルインジケータ付き
  • デュアル出力形式:要件に応じて16進数またはBase64エンコーディングで結果を生成
  • リアルタイム生成:入力時にHMACが即座に更新され、ボタンクリックは不要
  • クライアント側セキュリティ:Web Crypto APIを使用してすべての暗号化操作をローカルで実行。サーバーには何も送信されません
  • パスワード保護入力:秘密鍵フィールドはデフォルトでマスクされ、肩越し見を防止

ユースケース

  • API認証:HMACでAPIリクエストに署名して、リクエストの真正性を証明し、改ざんを防止(AWS、Stripeなど多くのサービスで使用)
  • Webhook検証:受信したWebhookが期待されるサービスから実際に送信されたことを検証(GitHub、Shopify、Twilio)
  • メッセージの完全性:システム間で送信されるメッセージが転送中に変更されていないことを確認
  • セッショントークン生成:データベース検索なしで検証できる安全なセッション識別子を作成
  • ドキュメントのデジタル署名:当事者間で共有される契約、合意、または機密ドキュメントの検証可能な署名を生成

セキュリティベストプラクティス

  1. 鍵の長さ:秘密鍵はハッシュ出力と同じ長さ以上を使用します(SHA-256の場合32バイト、SHA-512の場合64バイト)
  2. 鍵のランダム性:パスワードではなく、暗号化的に安全な乱数生成器を使用して鍵を生成
  3. 鍵の保存:ソースコードに鍵をハードコードしないでください。環境変数またはセキュアな鍵管理システムを使用
  4. アルゴリズム選択:SHA-256以上を使用します。新しい実装ではSHA-1を避けてください
  5. 定時間比較:HMACをプログラムで検証する場合、タイミング攻撃を防ぐために定時間比較関数を使用

一般的なHMAC実装

JavaScript(Node.js)

const crypto = require("crypto");
const hmac = crypto
  .createHmac("sha256", secretKey)
  .update(message)
  .digest("hex");

Python

import hmac
import hashlib
signature = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256).hexdigest()

PHP

$signature = hash_hmac('sha256', $message, $secretKey);

関連する標準および仕様

  • RFC 2104:HMAC:メッセージ認証用のキー付きハッシング
  • FIPS 198-1:キー付きハッシュメッセージ認証コード(HMAC)
  • RFC 4868:IPsecでのHMAC-SHA-256、HMAC-SHA-384、およびHMAC-SHA-512の使用