そもそも「ハッシュ化(SHA-256)」って何をするもの?
まず、「ハッシュ化」という言葉のイメージから整理します。
ハッシュ化は、ざっくり言うとこういう変換です。
入力: "hello"
出力: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
元の文字列(入力)から、決まった長さの「それっぽいランダムな文字列(ハッシュ値)」を作る処理です。
SHA-256 は、その中でもよく使われるハッシュ関数の一つで、「256ビット(64桁の16進数)」のハッシュ値を返します。
ここで大事なのは、次の性質です。
同じ入力からは、必ず同じハッシュ値が出る。
違う入力からは、ほぼ確実に違うハッシュ値が出る。
ハッシュ値から元の入力を「現実的な時間で」逆算することはできない(片方向)。
この性質のおかげで、SHA-256 は次のような用途でよく使われます。
データ改ざん検知(ファイルのハッシュ値を比べるなど)
トークンや識別子の「見た目を隠す」
ワンタイムトークンの保存用(トークンそのものではなくハッシュを保存)
パスワードそのものの保存には、SHA-256 単体は基本的に使いません(これは後で触れます)。
PHP で SHA-256 ハッシュを計算する基本
一番シンプルな形:hash(‘sha256’, $data)
PHP には、ハッシュを計算するための hash() 関数が標準で用意されています。
$input = 'hello';
$hash = hash('sha256', $input);
echo $hash;
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
PHP第一引数にアルゴリズム名(ここでは 'sha256')、
第二引数にハッシュ化したい文字列を渡します。
戻り値は「16進数文字列」です。
SHA-256 は 256ビット = 32バイトなので、16進数だと 64桁になります。
バイナリ形式で欲しい場合
hash() の第三引数に true を渡すと、「バイナリ形式(生の 32バイト)」で受け取れます。
$binary = hash('sha256', $input, true);
echo strlen($binary); // 32(バイト数)
PHPそのままだと表示しても意味が分からないので、
多くの場合は 16進文字列のまま扱うか、base64_encode() などでエンコードして使います。
小さなユーティリティ関数としてまとめる
「とりあえず SHA-256 の 16進文字列が欲しい」用
毎回 hash('sha256', ...) と書いてもいいのですが、
ユーティリティとして関数にしておくと、コードが読みやすくなります。
/**
* 文字列を SHA-256 でハッシュ化して 16進文字列を返す
*/
function sha256_hex(string $value): string
{
return hash('sha256', $value);
}
PHP使い方はとてもシンプルです。
echo sha256_hex('hello');
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
PHP「バイナリ形式が欲しい」+「Base64 で扱いたい」用
API トークンなどで、「Base64 形式のハッシュ値」を使いたいこともあります。
/**
* 文字列を SHA-256 でハッシュ化して Base64 文字列を返す
*/
function sha256_base64(string $value): string
{
$binary = hash('sha256', $value, true);
return base64_encode($binary);
}
PHP使い方の例です。
echo sha256_base64('hello');
// 例: "LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="
PHP16進数よりも少し短くなり、URL や JSON に載せるときに扱いやすいことがあります。
実務での使いどころ 1:トークンの「保存用ハッシュ」
なぜトークンをそのまま保存しないのか
ワンタイムトークンや API トークンを DB に保存するとき、
「トークンそのもの」を保存してしまうと、
もし DB が漏洩したときに、そのトークンがそのまま悪用されるリスクがあります。
そこでよくやるのが、
ユーザーには「生のトークン」を渡す
DB には「トークンの SHA-256 ハッシュ」を保存する
という設計です。
実装イメージ
トークン生成時のコードはこんな感じになります。
$token = generate_one_time_token(32); // さっきまでのワンタイムトークン生成関数など
$tokenHash = sha256_hex($token);
$stmt = $pdo->prepare('
INSERT INTO password_reset_tokens (user_id, token_hash, expires_at, created_at)
VALUES (:user_id, :token_hash, :expires_at, NOW())
');
$stmt->execute([
':user_id' => $userId,
':token_hash' => $tokenHash,
':expires_at' => $expiresAt,
]);
// ユーザーには生トークンを含んだ URL を送る
$url = 'https://example.com/reset-password?token=' . $token;
PHP検証時は、こうなります。
$token = $_GET['token'] ?? '';
$tokenHash = sha256_hex($token);
$stmt = $pdo->prepare('
SELECT * FROM password_reset_tokens
WHERE token_hash = :token_hash
LIMIT 1
');
$stmt->execute([':token_hash' => $tokenHash]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// あとは有効期限や未使用かどうかをチェック
PHPこうしておけば、DB に保存されているのは「ハッシュ値だけ」なので、
万が一漏洩しても、トークンそのものは分かりません(もちろん、他の対策も必要ですが、リスクは下がります)。
実務での使いどころ 2:データの改ざん検知
ファイルや設定の「ハッシュ値」を記録しておく
例えば、重要な設定ファイルやテンプレートファイルが、
意図せず書き換えられていないかをチェックしたいとします。
そのときに使えるのが「ハッシュ値の比較」です。
$path = '/path/to/config.php';
$content = file_get_contents($path);
$currentHash = sha256_hex($content);
// 事前に記録しておいたハッシュ値(DB や別ファイルに保存しておく)
$expectedHash = '...';
if (!hash_equals($expectedHash, $currentHash)) {
// 改ざんの可能性あり
}
PHPここで hash_equals() を使っているのは、
比較時のタイミング攻撃(比較時間から値を推測する攻撃)を避けるためです。
「ハッシュ値を比べる」という発想は、
ファイルだけでなく、JSON 設定、レスポンスキャッシュなどにも応用できます。
重要な注意点:パスワード保存に SHA-256 単体は使わない
ここは初心者が一番つまずきやすいポイントなので、しっかり分けておきます。
パスワードを保存するときに、
$hash = sha256_hex($password);
PHPとして DB に保存するのは、今の時代では「弱い」です。
理由は、次のような攻撃が現実的だからです。
総当たり攻撃(ブルートフォース)
レインボーテーブル攻撃(事前計算されたハッシュ表との照合)
パスワード保存には、PHP なら password_hash() / password_verify() を使うのが基本です。
$hash = password_hash($password, PASSWORD_DEFAULT);
// 検証時
if (password_verify($password, $hash)) {
// OK
}
PHPSHA-256 は、「パスワード以外のもの」に対して使う、
と覚えておくと安全です。
まとめ:今日からの「SHA-256 ハッシュ化」ユーティリティ
大事なポイントを整理すると、こうなります。
SHA-256 は「入力 → 64桁の16進文字列」に変換する片方向ハッシュ関数。
PHP では hash('sha256', $value) で簡単に計算できる。
トークンの保存用ハッシュや、ファイル・設定の改ざん検知などに実務でよく使う。
パスワード保存には SHA-256 単体ではなく、password_hash() を使う。
ユーティリティとしてまず一本持っておくと便利なのは、この関数です。
function sha256_hex(string $value): string
{
return hash('sha256', $value);
}
PHPそして、Base64 版が欲しければ、これを足します。
function sha256_base64(string $value): string
{
$binary = hash('sha256', $value, true);
return base64_encode($binary);
}
PHPもし、あなたのコードの中で「トークンをそのまま DB に保存している」「ファイルの改ざん検知を文字列比較だけでやっている」ような箇所があれば、そこがこのハッシュ化ユーティリティを差し込む絶好のポイントです。
その一箇所に SHA-256 を挟むだけで、「見え方」と「安全性」が一段階上がります。
