ハッシュ・HMAC生成
- MD5非推奨
- SHA-1非推奨
- SHA-256
- SHA-512
MD5とSHA-1は解読されており、パスワードや署名には使用できません。チェックサムやキャッシュキーとしては引き続き利用できます。
入力した内容が保存・記録・共有されることはありません。
テキストを入力すると、MD5・SHA-1・SHA-256・SHA-512のハッシュを同時に表示します。HMACモードでは秘密鍵による署名も生成できます。処理はすべてブラウザ内で行われ、テキストも鍵も端末外に出ることはありません。
使い方
- 入力欄にテキストを貼り付けます。
- 入力に応じて4種類のハッシュが計算されます。
- 各ハッシュの横のボタンでコピーします。
ハッシュが保証すること
暗号学的ハッシュは、任意の長さの入力を決定的に固定長のダイジェストへ変換します。同じバイト列からは常に同じ結果が得られ、1ビット変えるだけで出力のおよそ半分が変わります。有用性を支える性質は3つあり、用途によって必要な性質が異なります。
原像計算困難性とは、ダイジェストが与えられても、それを生み出す入力を見つけられないことです。第二原像計算困難性とは、ある入力が与えられても、同じダイジェストになる別の入力を見つけられないことです。衝突困難性とは、衝突する2つの入力をどんな組み合わせでも見つけられないことで、攻撃者が両方の入力を選べるため、3つの中で最も攻撃しやすい性質です。
この最後の違いこそが、破られたアルゴリズムでもすべての用途で等しく危険なわけではない理由です。MD5の衝突は数秒で作れますが、MD5のダイジェストを逆算できる人はいません。そのため、キャッシュキーや悪意を想定しないチェックサムとしてMD5を使うのは問題ありませんが、署名に使うのは問題です。
各アルゴリズムの現状
MD5は2004年から破られたものと見なされており、選択プレフィックス衝突、つまり攻撃者が意味の異なる2つのドキュメントを同じハッシュになるよう作り出す攻撃も、今では安価に行えます。2008年には実際に機能する認証局の偽造に、2012年にはマルウェアのFlameに利用されました。チェックサム、ETag、キャッシュキーには使えますが、攻撃者が改ざんして得をするようなものには決して使わないでください。
SHA-1も後に続きました。2017年に2つのPDFで初めて実用的な衝突が示され、2020年には数万ドル規模の費用で選択プレフィックス衝突が実現しました。ブラウザは何年も前にSHA-1証明書の受け入れをやめ、GitもSHA-1からの移行を進めています。寿命が少し長かっただけのMD5として扱ってください。
SHA-256とSHA-512が現在の標準で、実用上の弱点は知られていません。どちらも同じSHA-2ファミリーに属し、SHA-512は出力が長いにもかかわらず、64ビットのハードウェアではむしろ速いことがよくあります。SHA-3は置き換えではなく、構造の異なる予備として存在します。大きなファイルでの速度が重要な場面では、BLAKE3も知っておく価値があります。
HMACと、鍵とメッセージを一緒にハッシュしてはいけない理由
単純なハッシュは誰でも計算できるため、誰が作ったかについて何も証明しません。HMACは秘密鍵を加えるので、ダイジェストが一致すれば、送信者が鍵を知っていて、メッセージが改ざんされていないことを示せます。StripeやGitHubなど多くのサービスのWebhook配信の署名や、AWS APIリクエストの認証に使われているのがこれです。
直感的な構成、つまり鍵の後ろにメッセージを続けてハッシュする方法は、SHA-2ファミリーでは安全ではありません。これらはMerkle-Damgård構造の関数で、ダイジェストが内部状態そのものだからです。有効なダイジェストを1つ手に入れた攻撃者は、その状態から処理を再開してデータを追加でき、鍵を知らないまま、より長いメッセージに対する有効なダイジェストを作れます。2つの派生鍵で2回ハッシュするHMACの入れ子構造が、これを防いでいます。
検証時に必ず守るべき点が1つあります。ダイジェストの比較は定数時間で行うことです。通常の文字列比較は違いを見つけた時点で終了し、十分な回数のリクエストを重ねるとその時間差を測定できるため、攻撃者は署名を1バイトずつ割り出せます。ほとんどの言語には、このための専用関数が用意されています。
ハッシュは暗号化でもパスワード保存でもない
ハッシュは一方向で、鍵もありません。復号するものは何もなく、入力を取り戻す方法もありません。データを元に戻す必要があるなら、必要なのはまったく別の道具である暗号化です。
パスワードに高速なハッシュを使うのは、まさに誤った選択です。速さは攻撃者の味方です。一般向けのハードウェアでも、盗まれたデータベースに対して毎秒数十億回のSHA-256の推測を試せますし、ソルトのないダイジェストは事前計算したテーブルでそのまま引けてしまいます。パスワードの保存には、意図的に遅くメモリを大量に使う関数を、パスワードごとのソルトとともに使う必要があります。bcrypt、scrypt、そして現在の推奨であるArgon2idです。
もう少しわかりにくい誤用にも触れておきます。識別子を匿名化するためにハッシュすることです。メールアドレスや電話番号をハッシュしても何も守れません。入力として考えられる値の空間が、すべて列挙できるほど小さいからです。ダイジェストを入手した人は、手持ちのアドレスをすべてハッシュして照合できます。エントロピーの低い値のハッシュは、匿名化ではなく検索キーにすぎません。
ダウンロードを検証する手順
公開されているチェックサムが答えてくれるのは1つの問いだけです。受け取ったバイト列が、配布者の手元にあったバイト列と一致しているか、です。ファイルをローカルでハッシュし——macOSならshasum -a 256 file.iso、Linuxならsha256sum、PowerShellならGet-FileHash——ダウンロードページに載っているダイジェストと突き合わせます。1文字でも違えば、それは同じファイルではありません。
この比較でわからないのは、配布者のページ自体が本物かどうかです。攻撃者がダウンロードを差し替えられるのなら、その横に並んだチェックサムもたいてい差し替えられます。まじめなプロジェクトがダイジェストを載せるだけでなく、チェックサムファイルにGPG鍵で署名しているのはこのためです。まず署名を検証し、次にチェックサムを検証する。この連鎖があって初めて何かが証明されます。
同じ理由で、MD5は敵対者のいない状況でのチェックサムとしてはいまだに許容できる一方、署名としては許容できません。壊れたダウンロードを見つけるだけならMD5でも十分ですが、2つのファイルを同じダイジェストにしたい相手に対しては、2004年以来すでに破られています。
ハッシュは検査であると同時にアドレスでもある
現代のインフラの多くは、コンテンツを名前ではなくハッシュで識別します。Gitはすべてのオブジェクトを内容のダイジェストで名付けます。コミットの識別子が安定していて、改ざんが検出でき、リポジトリの置き場所に依存しないのはそのためです。コンテナイメージのダイジェストも同じ仕組みですし、パッケージのロックファイルも同様で、誰かが再公開できてしまうバージョン番号ではなく、正確なバイト列に依存関係を固定します。
重複排除も同じ発想です。ブロックごとにハッシュを取るバックアップシステムは同一のブロックを1度しか保存しませんし、CDNはダイジェストをキーにキャッシュしても古いデータを配ってしまう心配がありません。内容が違えばアドレスも違うからです。
マークルツリーはこれを拡張したものです。ハッシュのペアを上へ上へとハッシュしていくと、データセット全体にコミットする単一のルートダイジェストが得られます。これによってクライアントは、すべてをダウンロードしなくても、ある1つの項目がそこに含まれることを検証できます。Certificate Transparencyのログ、ブロックチェーン、いくつかのレプリケーション型データベースは、いずれもこの構造に依拠しています。
Webhookの署名を正しく検証する
このパターンはStripe、GitHub、Slackをはじめ、ほとんどのサービスで共通です。送信側は共有シークレットを使ってリクエストボディの生のバイト列のHMACを計算し、そのダイジェストをヘッダーに入れます。受信側は同じものを計算し直して比較します。実装が健全かどうかは4つの細部で決まります。
第一に、パースしたJSONを再シリアライズしたものではなく、生のボディをハッシュすること。キーの順序や空白が変わればバイト列が変わり、ダイジェストも変わります。第二に、定数時間で比較すること。通常の文字列比較は最初に差が出た位置を漏らすため、十分な数のリクエストを送ればそのタイミングから署名が組み立てられてしまいます。第三に、送信側が付けるタイムスタンプを署名対象のペイロードに含め、数分より古いものは拒否すること。そうしないと、捕捉されたリクエストをいつまでもリプレイされかねません。
第四に、2つのシークレットを同時にサポートすること。受信側が1つしか知らなければローテーションは不可能で、短い移行期間のあいだはどちらも受け入れるというのが一般的なやり方です。
パスワードハッシュのパラメータを選ぶ
現在の推奨はArgon2idで、単純なハッシュと違ってパラメータを取ります。メモリ、イテレーション、並列度です。専用ハードウェアを退けるのはメモリコストです。GPUやASICは演算能力に比べて、コアあたりの高速メモリがはるかに乏しいからです。よく使われる出発点はメモリ19 MiBにイテレーション2回で、ハードウェアが許すならさらに上げます。
チューニングは実測で行います。実際に動かすマシンで計測し、ログインがおおむね0.25秒以内に収まる範囲でもっとも高いコストを選びます。その際、ログインが集中するとそのコストが同時リクエストの数だけ掛け合わされることを忘れないでください。ワークファクタ12のbcryptも依然として許容範囲で、スタックによってはこちらのほうが導入しやすいでしょう。scryptはその中間に位置します。
移行に誰かのパスワードは必要ありません。ダイジェストごとにアルゴリズムとパラメータを一緒に保存し、検証は保存されたレコードの内容に従って行い、ログインが成功したその瞬間に新しい設定で再ハッシュします。数か月もあれば、アクティブなアカウントの大半はひとりでに移行し終わります。
ハッシュが道具として間違っている場面
識別子をハッシュして匿名化するという手は機能しません。その理由は暗記するよりも理解しておく価値があります。ハッシュは決定的であり、入力空間は小さいのです。メールアドレスも電話番号も数に限りがあるので、ダイジェストを持っている人は手元の候補をすべてハッシュして突き合わせられます。プライバシー保護をうたって売られてきた広告・分析の仕組みのいくつかは、まさにこの誤りの上に成り立っています。
識別子を明かさずに本当に突き合わせる必要があるなら、使うべきプリミティブは別物です。ほかの誰も持っていないシークレットを使う鍵付きハッシュか、private set intersectionのために設計されたプロトコルです。
よく見かける誤用がほかに2つあります。1つ、ハッシュは圧縮アルゴリズムではありません。そこから元の内容を復元することはできないからです。2つ、CRC32やMurmurHashのような非暗号学的ハッシュは、ハッシュテーブルやチェックサムには優れていますが、入力を敵対者が選べる場面では役に立ちません。衝突を意図的に作り出して、データ構造を線形探索にまで劣化させられるからです。
よくある質問
- HMACとは何で、どんなときに必要ですか?
- HMACはハッシュと秘密鍵を組み合わせ、その鍵を持つ相手からのメッセージであり改ざんされていないことを証明する仕組みです。通常のハッシュは誰でも再計算できるため、どちらも証明できません。WebhookのペイロードやAPIリクエストの署名に使われます。HMACモードに切り替えて鍵を入力してください。
- MD5は安全に使えますか?
- セキュリティ用途には使えません。MD5には実用的な衝突攻撃が存在し、パスワードや署名、悪意ある改ざんの検出には使用できません。チェックサムやキャッシュキーなど攻撃者を想定しない用途では引き続き有用なため、本ツールにも含めています。
- ではパスワードはどうハッシュ化すべきですか?
- ここにあるアルゴリズムは使わないでください。パスワード保存にはbcrypt、scrypt、Argon2など、意図的に低速でソルト付きの専用アルゴリズムが必要です。SHA-256のような高速な汎用ハッシュは毎秒数十億回の総当たりが可能です。
- 入力はサーバーに送信されますか?
- いいえ。SHA系はブラウザのWeb Crypto APIを使用し、MD5はページ内のJavaScriptで実装されているため、テキストが端末外に出ることはありません。
- なぜMD5はWeb Crypto APIに含まれていないのですか?
- 暗号学的に破られているため意図的に除外されています。そのため本ツールでは個別に実装し、RFC 1321の公式テストベクタで正しさを検証しています。
- 日本語にも対応していますか?
- はい。ハッシュ化の前にUTF-8へ変換されるため、日本語や絵文字でも一般的なコマンドラインツールと同じ結果が得られます。
最終更新:
操作手順、期待した結果、実際の結果を記載してください。秘密情報や個人情報は削除してください。
