ハッシュ関数はコンピュータサイエンスとサイバーセキュリティにおける最も重要な基盤の一つです。毎日、開発者とセキュリティ専門家がMD5ハッシュジェネレーター、SHA-256ハッシュ計算、その他のハッシュアルゴリズムを使用して、ファイルの完全性検証、パスワードの安全な保存、デジタル署名、ブロックチェーン技術を支えています。この包括的なガイドでは、基礎理論からJavaScript、Python、Bash、PowerShellの実践的なコード例まで、すべてをカバーします。
無料オンラインハッシュジェネレーターツールをお試しください — MD5、SHA-1、SHA-256、SHA-512対応。
ハッシュ関数とは?
ハッシュ関数は、任意のサイズの入力を受け取り、固定サイズの出力(ハッシュ値)を生成する数学的アルゴリズムです。例えば、"hello"のMD5ハッシュは常に5d41402abc4b2a76b9719d911017c592です。
ハッシュ関数には4つの基本的な特性があります:決定性、固定長出力、一方向性(原像耐性)、雪崩効果 — 入力のわずかな変更で出力が完全に変わります。
衝突耐性は暗号学的ハッシュ関数にとって重要です。SHA-256は安全なままですが、MD5とSHA-1には既知の衝突脆弱性があります。
一般的なハッシュアルゴリズムの比較
最も一般的なハッシュアルゴリズムの比較です:
| Algorithm | Output Size | Hex Length | Security Status | Speed | Use Cases |
|---|---|---|---|---|---|
| MD5 | 128 bits | 32 chars | Broken (2004) | Very Fast | Checksums, caching |
| SHA-1 | 160 bits | 40 chars | Broken (2017) | Fast | Git (legacy), fingerprints |
| SHA-256 | 256 bits | 64 chars | Secure | Moderate | Signatures, blockchain, TLS |
| SHA-512 | 512 bits | 128 chars | Secure | Moderate | High-security applications |
MD5は128ビットのダイジェストを生成し、2004年以降暗号学的に破られています。SHA-1は160ビットで、2017年にGoogleが実用的な攻撃を実証しました。SHA-256は256ビットで安全なまま。SHA-512は512ビットでより大きなセキュリティマージンを提供します。
セキュリティに敏感なアプリケーションにはSHA-256またはSHA-512を使用してください。
ハッシュ関数の仕組み
ほとんどの現代のハッシュ関数はMerkle-Damgard構造に従い、3つの主要段階で動作します:
1. メッセージパディング:メッセージはブロックサイズの倍数になるようパディングされます(SHA-256では512ビット)。
2. ブロック処理:パディングされたメッセージは固定サイズのブロックに分割され、ビット演算とローテーションを含む圧縮関数で処理されます。
3. 最終出力:すべてのブロック処理後、最終的な連鎖値がハッシュダイジェストとなります。
入力の1ビットの変更でも完全に異なるハッシュ出力が生成されます(雪崩効果)。
実用的なユースケース
ハッシュ関数は現代のコンピューティングのあらゆる場所で使用されています:
ファイル整合性検証:ダウンロードしたファイルのSHA-256ハッシュを公開値と比較します。
パスワード保存:安全なアプリケーションはパスワードをbcrypt、scrypt、またはArgon2でハッシュ化します。
デジタル署名:ソフトウェアはドキュメントのハッシュを計算し、秘密鍵で暗号化します。TLS/SSL証明書はハッシュ関数に依存しています。
Gitバージョン管理:GitはSHA-1ハッシュを使用して各コミットを一意に識別します。
ブロックチェーン:Bitcoinはブロックヘッダーとトランザクション検証にダブルSHA-256を使用します。
重複排除とキャッシュ:クラウドストレージシステムはハッシュを使用してバイト単位の比較なしに重複ファイルを検出します。
ハッシュ生成コード例
JavaScript(ブラウザとNode.js)
ブラウザではcrypto.subtle.digestを、Node.jsではcryptoモジュールを使用します:
// ===== Browser: Web Crypto API (SHA-256) =====
async function sha256(message) {
const encoder = new TextEncoder();
const data = encoder.encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// Usage
const hash = await sha256('Hello World');
console.log(hash);
// "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
// Supports SHA-1, SHA-256, SHA-384, SHA-512
async function hashDigest(message, algorithm = 'SHA-256') {
const data = new TextEncoder().encode(message);
const buffer = await crypto.subtle.digest(algorithm, data);
return Array.from(new Uint8Array(buffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
await hashDigest('hello', 'SHA-1'); // "aaf4c61d..."
await hashDigest('hello', 'SHA-256'); // "2cf24dba..."
await hashDigest('hello', 'SHA-512'); // "9b71d224..."
// ===== Node.js: crypto module =====
const crypto = require('crypto');
// MD5 hash
const md5 = crypto.createHash('md5').update('Hello World').digest('hex');
console.log(md5); // "b10a8db164e0754105b7a99be72e3fe5"
// SHA-1 hash
const sha1 = crypto.createHash('sha1').update('Hello World').digest('hex');
console.log(sha1); // "0a4d55a8d778e5022fab701977c5d840bbc486d0"
// SHA-256 hash
const sha256 = crypto.createHash('sha256').update('Hello World').digest('hex');
console.log(sha256); // "a591a6d40bf420404a011733cfb7b190..."
// SHA-512 hash
const sha512 = crypto.createHash('sha512').update('Hello World').digest('hex');
console.log(sha512); // "2c74fd17edafd80e8447b0d46741ee24..."
// Hash a file
const fs = require('fs');
function hashFile(filePath, algorithm = 'sha256') {
return new Promise((resolve, reject) => {
const hash = crypto.createHash(algorithm);
const stream = fs.createReadStream(filePath);
stream.on('data', data => hash.update(data));
stream.on('end', () => resolve(hash.digest('hex')));
stream.on('error', reject);
});
}
const fileHash = await hashFile('./package.json', 'sha256');Python(hashlib)
PythonはhashlibモジュールでMD5、SHA-1、SHA-256などを提供します:
import hashlib
# MD5 hash
md5_hash = hashlib.md5("Hello World".encode('utf-8')).hexdigest()
print(md5_hash) # "b10a8db164e0754105b7a99be72e3fe5"
# SHA-1 hash
sha1_hash = hashlib.sha1("Hello World".encode('utf-8')).hexdigest()
print(sha1_hash) # "0a4d55a8d778e5022fab701977c5d840bbc486d0"
# SHA-256 hash
sha256_hash = hashlib.sha256("Hello World".encode('utf-8')).hexdigest()
print(sha256_hash) # "a591a6d40bf420404a011733cfb7b190..."
# SHA-512 hash
sha512_hash = hashlib.sha512("Hello World".encode('utf-8')).hexdigest()
print(sha512_hash) # "2c74fd17edafd80e8447b0d46741ee24..."
# Hash a file (memory-efficient for large files)
def hash_file(filepath, algorithm='sha256'):
h = hashlib.new(algorithm)
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(8192), b''):
h.update(chunk)
return h.hexdigest()
file_hash = hash_file('document.pdf', 'sha256')
print(f"SHA-256: {file_hash}")
# Compare file hashes for integrity verification
def verify_integrity(filepath, expected_hash, algorithm='sha256'):
actual_hash = hash_file(filepath, algorithm)
return actual_hash == expected_hash
# List all available hash algorithms
print(hashlib.algorithms_available)
# {'md5', 'sha1', 'sha256', 'sha512', 'sha3_256', ...}Bash / Linux
LinuxとmacOSはmd5sum、sha256sum、openssl dgstを提供します:
# MD5 hash of a string
echo -n "Hello World" | md5sum
# b10a8db164e0754105b7a99be72e3fe5 -
# SHA-1 hash of a string
echo -n "Hello World" | sha1sum
# 0a4d55a8d778e5022fab701977c5d840bbc486d0 -
# SHA-256 hash of a string
echo -n "Hello World" | sha256sum
# a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e -
# SHA-512 hash of a string
echo -n "Hello World" | sha512sum
# 2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f2... -
# Hash a file
md5sum package.json
sha256sum package.json
sha512sum package.json
# Using openssl (works on both Linux and macOS)
echo -n "Hello World" | openssl dgst -md5
echo -n "Hello World" | openssl dgst -sha1
echo -n "Hello World" | openssl dgst -sha256
echo -n "Hello World" | openssl dgst -sha512
# Hash a file with openssl
openssl dgst -sha256 package.json
# macOS uses shasum instead of sha256sum
echo -n "Hello World" | shasum -a 256
echo -n "Hello World" | shasum -a 512
# Verify a downloaded file against a known hash
echo "expected_hash_here filename" | sha256sum --check
# Hash all files in a directory
find . -type f -exec sha256sum {} \;PowerShell(Get-FileHash)
PowerShellはファイル用のGet-FileHashと文字列用の.NETクラスを提供します:
# Hash a file with Get-FileHash (SHA-256 is default)
Get-FileHash -Path "C:\document.pdf"
Get-FileHash -Path "C:\document.pdf" -Algorithm MD5
Get-FileHash -Path "C:\document.pdf" -Algorithm SHA1
Get-FileHash -Path "C:\document.pdf" -Algorithm SHA256
Get-FileHash -Path "C:\document.pdf" -Algorithm SHA512
# Hash a string (MD5)
$md5 = [System.Security.Cryptography.MD5]::Create()
$bytes = [System.Text.Encoding]::UTF8.GetBytes("Hello World")
$hash = $md5.ComputeHash($bytes)
$hashString = [BitConverter]::ToString($hash).Replace("-", "").ToLower()
Write-Output $hashString
# "b10a8db164e0754105b7a99be72e3fe5"
# Hash a string (SHA-256)
$sha256 = [System.Security.Cryptography.SHA256]::Create()
$bytes = [System.Text.Encoding]::UTF8.GetBytes("Hello World")
$hash = $sha256.ComputeHash($bytes)
$hashString = [BitConverter]::ToString($hash).Replace("-", "").ToLower()
Write-Output $hashString
# "a591a6d40bf420404a011733cfb7b190..."
# Reusable function for string hashing
function Get-StringHash {
param(
[string]$InputString,
[string]$Algorithm = "SHA256"
)
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)
$bytes = [System.Text.Encoding]::UTF8.GetBytes($InputString)
$hash = $hasher.ComputeHash($bytes)
return [BitConverter]::ToString($hash).Replace("-", "").ToLower()
}
Get-StringHash "Hello World" "MD5"
Get-StringHash "Hello World" "SHA256"
Get-StringHash "Hello World" "SHA512"
# Verify file integrity
$expected = "a591a6d40bf420404a011733cfb7b190..."
$actual = (Get-FileHash -Path "file.zip" -Algorithm SHA256).Hash.ToLower()
if ($actual -eq $expected) { "MATCH" } else { "MISMATCH" }MD5 vs SHA-256:どちらを使うべきか?
MD5は暗号学的に破られています — 衝突は数秒で生成できます。セキュリティが重要なアプリケーションにMD5は安全ではありません。
MD5が許容される場面:非暗号チェックサム、キャッシュキー、重複排除、HTTP ETag。
SHA-256が必要な場面:デジタル署名、証明書、パスワードハッシュ、ブロックチェーン、コード署名、API認証用HMAC。
結論:迷ったら常にSHA-256を選択してください。
ハッシュセキュリティのベストプラクティス
開発者のための基本的なベストプラクティスです:
パスワードをプレーンなMD5/SHA-256でハッシュしない:bcrypt、scrypt、またはArgon2を使用してください。
常にソルトを使用する:ソルトはハッシュ前にパスワードに追加されるユーザー固有のランダム値で、レインボーテーブル攻撃を防ぎます。
メッセージ認証にHMACを使用する:HMAC-SHA256はAPI認証の業界標準です(AWS、Stripe、GitHub Webhookなど)。
長さ拡張攻撃を避ける:Hash(secret + message)の代わりにHMACを使用してください。
定数時間でハッシュを比較する:Node.jsではcrypto.timingSafeEqual()、Pythonではhmac.compare_digest()を使用してください。
よくある質問
MD5とSHA-256の違いは何ですか?
MD5は128ビットのハッシュを生成し暗号学的に破られています。SHA-256は256ビットのハッシュを生成し安全なままです。MD5は高速ですが非セキュリティ用途のチェックサムにのみ使用すべきです。
MD5はまだ安全ですか?
MD5は暗号用途には安全ではありません。非セキュリティチェックサム、キャッシュキー、重複排除には許容されます。
ハッシュを逆変換できますか?
いいえ、ハッシュ関数は一方向に設計されています。ただし、弱いパスワードはブルートフォースやレインボーテーブルで「クラック」される可能性があります。パスワードにはbcryptやArgon2を使用してください。
ハッシュ関数は現代のコンピューティングとサイバーセキュリティの基本的な柱です。セキュリティにはSHA-256を、パスワードにはbcrypt/Argon2を、メッセージ認証にはHMACを使用してください。