ハッシュとは
ハッシュ(hash/ハッシュ)は、任意長の入力から一定長の値を計算する一方向性の関数、またはその出力です。暗号学的ハッシュでは、入力からダイジェストを速く計算できても、ダイジェストから元入力を現実的に求めにくい性質を狙います。
同じアルゴリズムと同じバイト列なら同じ値になり、一ビットでも変わると出力全体が大きく変わるavalanche effect(アバランチ・エフェクト/雪崩効果)を持ちます。
ハッシュ値が違えばデータも違いますが、ハッシュ値が同じだからといって数学的に同一とは断定できません。有限長の出力へ無限個の入力を写すため、衝突自体は必ず存在します。

暗号学的ハッシュに求める三つの困難性
与えられたダイジェストになる入力を新たに見つけにくい性質です。
既知の入力と同じダイジェストになる別入力を見つけにくい性質です。
同じダイジェストになる任意の異なる二入力を見つけにくい性質です。
同じバイト列とアルゴリズムからは毎回同じダイジェストを得ます。
衝突は「見つからない」強度を考える
nビットの理想的ハッシュでは、特定ダイジェストの原像探索はおおむね2のn乗規模、任意衝突は誕生日境界によりおおむね2のn/2乗規模が目安です。これは保証された試行回数ではなく、安全強度を比較するモデルです。
MD5やSHA-1は実用的衝突攻撃が知られ、署名や敵対的入力の完全性には使いません。互換用識別値として残っていても、セキュリティ用途のアルゴリズム選定とは分けます。
ハッシュは暗号化ではない
暗号化は鍵を使って平文を復号可能な暗号文へします。ハッシュは通常鍵を取らず、元へ戻す操作を定義しません。短い候補や辞書にある値は、候補を順にハッシュして一致を探せます。
そのため「ハッシュ化した電話番号」や単純なIDは匿名化にならない場合があります。入力空間、ソルト、鍵付き仮名化、再識別リスクを評価します。
ファイル照合はダイジェストの入手経路が重要
ダウンロードファイルのダイジェストを再計算し、公開値と比べれば転送破損を検出できます。しかしファイルとダイジェストを同じ改ざん可能なサーバーから取るだけでは、攻撃者が両方を置き換えられます。
ダイジェストをHTTPS、署名済み公開、別の認証済み通信路から取得します。アルゴリズム名と大文字小文字・区切りを含む表記を明示します。
HMACは秘密鍵で真正性を加える
HMAC(Hash-based Message Authentication Code/ハッシュ・ベースド・メッセージ・オーセンティケーション・コード/エイチマック)は、秘密鍵とハッシュを規定の内外二段構造で組み合わせるMACです。
単純なhash(key || message)はアルゴリズムによって長さ拡張攻撃等の問題があります。WebhookやAPI署名では仕様どおりHMACを計算し、入力値によらず一定時間で動く比較、時刻印、再利用防止も行います。
デジタル署名では署名対象の要約に使う
大きな文書を直接公開鍵演算へ入れず、規定のハッシュで要約して署名方式へ渡します。検証側は同じバイト表現からダイジェストを計算します。
空白、改行、性質順が違えばダイジェストが変わるため、プロトコルが定める正規化を先に行います。見た目が同じという理由で独自に整形しません。
パスワードを高速ハッシュ一回で保存しない
SHA-256のような高速ハッシュは大量候補を試せるため、パスワード保存へ単独使用しません。利用者ごとの乱数ソルトと、Argon2id・scrypt・bcrypt・PBKDF2等のパスワードハッシュ化/KDFを使います。
コストパラメーターを環境に合わせて上げ、ペッパーを使う場合はデータベース外の秘密情報として管理します。ソルトは秘密ではなく、同じパスワードのダイジェストを利用者ごとに変える値です。
暗号学的ハッシュは任意長入力から固定長ダイジェストを作り、原像・第二原像・衝突を見つけにくくします。完全性だけでなく真正性が必要ならHMACや署名を使い、パスワードには専用の低速KDFを使います。
SHA familyのsecure hash要件とalgorithm:NIST FIPS 180-4 Secure Hash Standard/HMAC:RFC 2104