ハッシュ生成
ハッシュジェネレーターは、MD5、SHA-1、SHA-256、SHA-384、SHA-512、CRC32、HMACをブラウザ内で計算します。どの結果にも、そのアルゴリズムのセキュリティ状況が付きます。MD5とSHA-1について最も重大な事実は、両者とも破られていることであり、それを告げずに提供するツールは問題の一翼を担っているからです。
| アルゴリズム | 状態 | ハッシュ値 | コピー |
|---|---|---|---|
| MD5128 | 安全でない | … | |
| SHA-1160 | 安全でない | … | |
| SHA-256256 | 現行 | … | |
| SHA-384384 | 現行 | … | |
| SHA-512512 | 現行 | … | |
| CRC3232 | チェックサム | … |
ハッシュ生成はどう動きますか?
ハッシュは、任意の入力を固定長の値へ対応付ける関数で、同じ出力になる2つの入力を見つけることが不可能である「はず」のものです。この「はず」に話のすべてがかかっており、どのアルゴリズムが今もそれを満たすのかこそ、このページが伝えられる最も有用な情報です。
MD5とSHA-1は破られており、しかも理論の話ではない
MD5の衝突はノートPCでも数秒で作れ、実際に悪用された実績もあります。2012年には、FlameマルウェアがMD5衝突を使ってMicrosoftのコード署名証明書を偽造しました。SHA-1は2017年、GoogleとCWIが同じダイジェストを持つ2つのPDFを作成したことで陥落し、それ以降コストは下がる一方です。どちらも、署名、敵対者に備える整合性の検証、管理外の入力の重複排除には使えません。セキュリティと無関係なチェックサムとしては問題なく、今もどこにでもあります——だからこそこのページに載っているのです。
ハッシュはパスワードハッシュではない
SHA-256は速さを狙って設計されています。GPU上では毎秒数十億回の処理が可能です。パスワードにとって、速さこそがまさに誤りです。パスワードの防御は、推測のコストがパスワードの価値を上回るほど遅いことにあります。パスワードのSHA-256を保存する(saltの有無を問わず)と、データベースを手にした攻撃者は、よく使われるパスワードのリスト全体を数分で試せます。正しい道具はbcrypt、scrypt、Argon2で、いずれも意図的なコスト係数を持ちます。このページのどの機能もパスワードハッシュではありません。
HMACは「鍵とメッセージをハッシュする」ことではない
素朴な構成であるH(key || message)は、Merkle–Damgård型のハッシュ——MD5、SHA-1、SHA-256が含まれます——では破られています。ダイジェストと鍵の長さを知っている攻撃者は、鍵を一度も見ることなく、データを末尾に追加して、拡張後のメッセージの有効なダイジェストを計算できます。これがlength extension攻撃であり、HMACが入れ子になった内側と外側のハッシュを持つ独立したプリミティブとして存在する理由です。SHA-384とSHA-512/256は切り詰め方式のため、構造的にこの攻撃を受けません。
入力のエンコーディングでハッシュは変わる
ハッシュは文字ではなくバイト列に対して定義されます。そのためcaféのダイジェストは、アクセント付きの文字がUTF-8の2バイトC3 A9なのか、Latin-1の1バイトE9なのかで変わります。このページは全体を通してUTF-8を使います。現在のどのシステムもこれを指します。ローカルでは検証に成功し、本番環境で失敗する署名は、大抵これが原因です。
CRC32はそもそもハッシュではない
CRC32は伝送エラーを検出するために設計されたチェックサムで、意図的に衝突を作るのは容易です。32ビットしかないため、誕生日の限界(birthday bound)により、約65,000件の入力で偶然の衝突も起こりえます。ダウンロードの破損を検知するには正しい道具であり、それ以外には向いていません。
入力
abc
ダイジェスト
MD5 900150983cd24fb0d6963f7d28e17f72 broken SHA-1 a9993e364706816aba3e25717850c26c9cd0d89d broken SHA-256 ba7816bf8f01cfea414140de5dae2223b0… current
ハッシュ生成が対応するオプションとエッジケースは?
| パラメータ | 型 | デフォルト | 動作とエッジケース |
|---|---|---|---|
| MD5 | 128-bit | 脆弱 | ラップトップ上での衝突が実際に可能であり、実際の攻撃で使用されたことがあります。セキュリティチェックサムとして問題ありません。署名、敵対者に対する完全性、信頼できない入力の重複排除には絶対に使用しないでください。 |
| SHA-1 | 160-bit | 脆弱 | SHAtteredが2017年に実際の衝突を生成し、そのコストは以来低下しています。ブラウザと証明書認証局はこれを廃止しました。Gitは引き続きオブジェクト名に使用していますが、これはセキュリティではなく互換性のための決定です。 |
| SHA-256 | 256-bit | 現行 | 現在の完全性と署名のデフォルトです。実際的な攻撃はありません。設計上高速であるため、パスワードのハッシュには不適切な選択です。 |
| SHA-384 | 384-bit | 現行 | SHA-512を切り詰めたものです。これにより、SHA-256に影響する長さ拡張攻撃から免疫になります。その特性が重要な場所で選ばれます。 |
| SHA-512 | 512-bit | 現行 | 出力が大きいにもかかわらず、64ビットハードウェア上ではSHA-256よりも高速です。追加の長さがコストにならない場所では優先する価値があります。 |
| CRC32 | 32-bit | チェックサム | エラー検出用のチェックサムであり、ハッシュではありません。意図的に偽造するのは容易で、約65,000個の入力で偶発的に衝突します。破損した転送をキャッチするには正しいですが、それ以外には間違っています。 |
| HMAC | 鍵付き | SHA系のみ | キー付きの構造で、キーとメッセージを一緒にハッシュするのとは異なり、長さ拡張に抵抗します。SHAアルゴリズム用に提供されます。破損したハッシュ上のHMACは破損したMACになるため、MD5とCRC32は除外されます。 |
| 入力エンコーディング | UTF-8 | 常に | ハッシュはバイト上で定義されます。同じテキストのダイジェストはUTF-8とLatin-1で異なり、これはローカルで検証されながら本番環境で失敗する署名の繰り返しの原因です。 |
| 出力 | hex/base64 | hex | 2つのレンダリングにおける同じバイトです。Hexはコマンドラインツールが表示するものです。base64は多くのHTTPヘッダーが運ぶものです。 |
よくある質問
パスワードのハッシュ化に使えますか?
いいえ。そしてこれが、このページで最も重要な答えです。ここにあるアルゴリズムはどれも速く動くように設計されていますが、パスワードには速さこそ要りません。データベースとGPUを手にした攻撃者は、毎秒数十億の候補を試します。bcrypt、scrypt、Argon2を使ってください。いずれも調整可能なコスト係数を持ち、1回の推測を高くつかせられます。SHA-256にsaltを加えるのはレインボーテーブルには有効でも、最新のクラッキング環境には何の役にも立ちません。
まだあちこちで使われているMD5は、本当に破られているのですか?
どちらも事実です。衝突は現実に作れて、ノートPCでも同じMD5を持つ2つのファイルが作れます。MD5の衝突は実際の攻撃で、Microsoftのコード署名証明書の偽造に使われました。一方で、セキュリティと無関係なチェックサムとしてのMD5は今もあちこちにあります。ETagや、偶発的な破損を検知するファイル整合性チェックです。その用途なら問題ありません。まずいのは、敵対者が入力を選べる場面です。
自分のダイジェストが別のツールの結果と違うのはなぜですか?
ほとんどの場合、原因はアルゴリズムではなく入力です。まず末尾の改行を確認してください。ファイルは改行で終わるのが普通で、テキストボックスはそうでないことが多く、1バイトの違いが結果をすべて変えます。次にエンコーディングを確認します。このページはUTF-8を使います。Latin-1が既定のツールなら、非ASCII文字で違うダイジェストになります。最後に、相手のツールがファイルのバイト列をハッシュしたのか、そのbase64表現をハッシュしたのかを確認してください。
HMACは何のためにありますか?
メッセージが共有秘密を知る者から来たものであり、改ざんされていないことを証明するためです。Webhookのペイロード、APIリクエスト、セッションクッキーの署名に使われているのがこれです。鍵とメッセージをまとめてハッシュするのではなく独立したプリミティブになっている理由は、length extensionです。多くのハッシュでは、H(key || message)を知っているだけで、攻撃者は鍵なしに、より長いメッセージの有効なダイジェストを計算できてしまいます。HMACの入れ子構造はそれを防ぎます。
どのSHAを使うべきですか?
特別な理由がなければSHA-256です。どこでも標準で、十分に分析されており、十分に速いからです。SHA-512は出力が長いにもかかわらず、64ビットハードウェアでは実際に速く動きます。SHA-384はSHA-512を切り詰めたもので、length extensionを受けず、HMACを使わずに秘密値を直接ハッシュするものを作るなら正しい選択です。
入力はアップロードされますか?
いいえ。SHAのハッシュ計算にはブラウザ内蔵のSubtleCryptoを使います。MD5とCRC32は、SubtleCryptoが意図的にMD5の実装を拒んでいるため、このページ上でJavaScriptで実装しています。何もタブの外に出ません。ハッシュ化されるものは、APIの秘密、トークン、ファイルの中身であることが多いので、これは重要です。