暗号化とハッシュ化の違いを徹底解説:セキュリティの基本概念|Python実装例付き
はじめに
情報セキュリティの分野でよく耳にする「暗号化」と「ハッシュ化」。似たような概念に思えますが、実は全く異なる目的と仕組みを持つ重要な技術です。
この記事では、暗号化とハッシュ化の違いを分かりやすく解説し、実際のPythonコードを使って両者の特徴を理解していきます。
暗号化とハッシュ化の基本的な違い
暗号化(Encryption)
可逆性があるデータ保護技術です。暗号化されたデータは復号化キーを使って元のデータに戻すことができます。
ハッシュ化(Hashing)
不可逆性があるデータ変換技術です。一度ハッシュ化されたデータは元の形に戻すことができません。
暗号化の詳細解説
暗号化の特徴
- 双方向性: 暗号化 ⇔ 復号化が可能
- 機密性: データの内容を第三者から隠す
- キー依存: 暗号化・復号化にキーが必要
- 可変長出力: 元データのサイズに応じて出力サイズが変わる
暗号化の種類
1. 共通鍵暗号化(対称暗号)
- 暗号化と復号化に同じキーを使用
- 高速処理が可能
- 例:AES、DES
2. 公開鍵暗号化(非対称暗号)
- 公開鍵と秘密鍵のペアを使用
- 安全な鍵交換が可能
- 例:RSA、楕円曲線暗号
暗号化の実装例
AES暗号化(共通鍵)
from cryptography.fernet import Fernet
# キー生成と暗号化
key = Fernet.generate_key()
cipher = Fernet(key)
encrypted = cipher.encrypt(b"秘密のメッセージ")
decrypted = cipher.decrypt(encrypted)
print(decrypted.decode()) # 秘密のメッセージ
RSA暗号化(公開鍵)
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding
# キーペア生成
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
# 暗号化と復号化
message = b"機密データ"
encrypted = public_key.encrypt(message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None))
decrypted = private_key.decrypt(encrypted, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None))
ハッシュ化の詳細解説
ハッシュ化の特徴
- 一方向性: 元データの復元が不可能
- 固定長出力: 入力サイズに関係なく一定の出力長
- 決定性: 同じ入力は常に同じハッシュ値を生成
- 雪崩効果: 僅かな入力変化で大幅にハッシュ値が変化
ハッシュ関数の種類
1. 暗号学的ハッシュ関数
- SHA-256、SHA-3、Blake2
- セキュリティが重要な用途
2. 非暗号学的ハッシュ関数
- MD5、CRC32
- 高速処理が必要な用途
ハッシュ化の実装例
SHA-256ハッシュ
import hashlib
data = "パスワード123"
hash_value = hashlib.sha256(data.encode()).hexdigest()
print(hash_value) # 64文字の16進数文字列
複数ハッシュアルゴリズムの比較
import hashlib
text = "ハッシュ化テスト"
print("MD5:", hashlib.md5(text.encode()).hexdigest())
print("SHA-1:", hashlib.sha1(text.encode()).hexdigest())
print("SHA-256:", hashlib.sha256(text.encode()).hexdigest())
ソルト付きハッシュ
import hashlib
import os
password = "mypassword"
salt = os.urandom(32) # 32バイトのランダムソルト
pwdhash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
暗号化 vs ハッシュ化:比較表
項目 | 暗号化 | ハッシュ化 |
---|---|---|
可逆性 | 可逆(復号化可能) | 不可逆(復元不可能) |
目的 | データの機密性保持 | データの整合性確認 |
出力長 | 可変長 | 固定長 |
キー | 必要 | 不要 |
処理速度 | 比較的遅い | 高速 |
用途 | 通信・保存時の秘匿化 | パスワード保存・データ検証 |
実用的な使い分け
暗号化を使う場面
1. データ通信の保護
# HTTPSでの通信データ暗号化
import requests
response = requests.get('https://api.example.com', verify=True)
2. ファイル暗号化
from cryptography.fernet import Fernet
with open('secret.txt', 'rb') as f:
data = f.read()
key = Fernet.generate_key()
encrypted_data = Fernet(key).encrypt(data)
3. データベース暗号化
# 機密情報の暗号化保存
encrypted_credit_card = cipher.encrypt(credit_card_number.encode())
ハッシュ化を使う場面
1. パスワード保存
import bcrypt
password = "user_password"
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
# データベースにhashedを保存
2. データ整合性チェック
import hashlib
def verify_file_integrity(file_path, expected_hash):
with open(file_path, 'rb') as f:
file_hash = hashlib.sha256(f.read()).hexdigest()
return file_hash == expected_hash
3. デジタル署名
# ドキュメントのハッシュ値を計算して署名
document_hash = hashlib.sha256(document.encode()).digest()
セキュリティ上の注意点
暗号化の注意点
- キー管理: 暗号化キーの安全な保管が重要
- アルゴリズム選択: 古い暗号化方式(DES、MD5など)は避ける
- 実装の複雑さ: 暗号化ライブラリの正しい使用
ハッシュ化の注意点
- レインボーテーブル攻撃: ソルトの使用が必須
- 辞書攻撃: 強固なパスワードポリシーが必要
- ハッシュ関数選択: SHA-256以上の使用を推奨
実践的なセキュリティ実装
安全なパスワード管理システム
import bcrypt
import getpass
def hash_password(password):
return bcrypt.hashpw(password.encode(), bcrypt.gensalt())
def verify_password(password, hashed):
return bcrypt.checkpw(password.encode(), hashed)
# 使用例
password = getpass.getpass("パスワード: ")
hashed = hash_password(password)
ファイル暗号化システム
from cryptography.fernet import Fernet
import base64
def encrypt_file(filename, key):
with open(filename, 'rb') as f:
data = f.read()
encrypted = Fernet(key).encrypt(data)
with open(filename + '.encrypted', 'wb') as f:
f.write(encrypted)
よくある誤解と正しい理解
誤解1: ハッシュ化も暗号化の一種
正解: ハッシュ化は暗号化ではありません。復号化できない一方向関数です。
誤解2: MD5やSHA-1はまだ安全
正解: MD5とSHA-1は脆弱性が発見されており、現在は非推奨です。
誤解3: 暗号化すれば完全に安全
正解: 暗号化は完璧ではなく、キー管理や実装方法が重要です。
選択の指針
暗号化を選ぶべき場合
- データを後で復元する必要がある
- 通信内容を秘匿したい
- ファイルを安全に保管したい
ハッシュ化を選ぶべき場合
- パスワードを保存したい
- データの改ざんを検出したい
- デジタル署名を作成したい
まとめ
暗号化とハッシュ化は、それぞれ異なる目的とメカニズムを持つ重要なセキュリティ技術です。
暗号化は可逆的なデータ保護技術として機密性を確保し、ハッシュ化は不可逆的なデータ変換技術としてデータの整合性と認証を担います。
適切な技術選択と正しい実装により、堅牢なセキュリティシステムを構築できます。セキュリティは継続的な学習と実践が重要であり、最新の脅威動向にも注意を払い続けることが大切です。
関連キーワード: 暗号化, ハッシュ化, セキュリティ, AES暗号化, SHA-256, パスワード保護, データ保護, Python暗号化, 情報セキュリティ, 暗号学
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座