MD5 vs SHA-1 vs SHA-256: ハッシュアルゴリズムの比較

· 12分で読めます

目次

ハッシュ化の詳細な理解

ハッシュ関数は安全なコンピューティングの基盤を形成し、任意の入力データをハッシュまたはダイジェストと呼ばれる固定サイズの文字列に変換します。この暗号化プロセスは基本的に一方向です。ハッシュ出力だけから元の入力をリバースエンジニアリングすることはできません。

この不可逆性により、ハッシュ化はデータ整合性の検証、デジタル署名の生成、パスワードストレージの保護、分散システムにおけるデータブロックの一意識別子の作成などのアプリケーションに非常に有用です。

実用的なシナリオを考えてみましょう。インターネットからソフトウェアをダウンロードする際、プロバイダーはダウンロードリンクと一緒にMD5またはSHA-256ハッシュを含めることがよくあります。ダウンロード後、ファイルをローカルでハッシュ化し、結果を公開されたハッシュと比較できます。一致すれば、転送中にファイルが破損または改ざんされていないことを確認できます。

プロのヒント: 当社のハッシュ計算機を使用して、コードを書かずに任意のテキストやファイルのMD5、SHA-1、SHA-256ハッシュを即座に生成・比較できます。

ハッシュには、セキュリティアプリケーションに有用ないくつかの重要な特性があります:

ハッシュ関数の仕組み

ハッシュ関数は本質的に、複数ラウンドの操作を通じて入力データに数学的変換を適用します。これらの操作には通常、ビット演算、モジュラー演算、データを複雑で不可逆的な方法でスクランブルする論理関数が含まれます。

プロセスは一般的に次の手順に従います:

  1. パディング: 入力は特定の長さ要件を満たすようにパディングされます
  2. 解析: パディングされた入力は固定サイズのブロックに分割されます
  3. 処理: 各ブロックは圧縮関数を使用して複数ラウンドの変換を受けます
  4. 最終化: 最終状態がハッシュ出力に変換されます

雪崩効果はセキュリティにとって特に重要です。入力の1ビットでも変更すると、出力ハッシュのビットの約半分が変更されるはずです。この特性により、類似した入力が類似したハッシュを生成しないことが保証され、攻撃者が元のデータについて推測することを防ぎます。

「優れたハッシュ関数はランダムオラクルと区別がつかないものであるべきです。つまり、入力とは完全にランダムで無相関に見える出力を生成します。」— ブルース・シュナイアー、応用暗号理論

MD5: 機能、制限、および現代の使用例

MD5(メッセージダイジェストアルゴリズム5)は、1991年にロナルド・リベストによってMD4の改良版として設計されました。128ビット(16バイト)のハッシュ値を生成し、通常は32文字の16進数として表されます。

MD5はその速度とシンプルさから広く採用されました。長年にわたり、チェックサム、パスワードハッシュ化、デジタル署名の定番アルゴリズムでした。しかし、時間の経過とともに発見された暗号学的弱点により、セキュリティが重要でないアプリケーションに限定されるようになりました。

技術仕様

コード実装

PythonでMD5ハッシュを生成する方法は次のとおりです:

import hashlib

def get_md5_hash(input_data):
    """入力文字列からMD5ハッシュを生成"""
    return hashlib.md5(input_data.encode()).hexdigest()

# 使用例
text = "hash this string"
hash_result = get_md5_hash(text)
print(f"MD5: {hash_result}")
# 出力: c13b0a8f21c9b3a0b49c3cb482dd82b4

# ファイルのハッシュ化
def hash_file_md5(filename):
    """ファイルのMD5ハッシュを生成"""
    md5_hash = hashlib.md5()
    with open(filename, "rb") as f:
        # 大きなファイルを処理するためにチャンクで読み込む
        for chunk in iter(lambda: f.read(4096), b""):
            md5_hash.update(chunk)
    return md5_hash.hexdigest()

セキュリティ脆弱性

MD5の主な弱点は、衝突攻撃に対する脆弱性です。2004年、研究者は実用的な衝突攻撃を実証し、同一のMD5ハッシュを生成する2つの異なる入力を作成できることを示しました。2008年までに、攻撃者はMD5衝突を使用して不正なSSL証明書を作成しました。

その影響は深刻です。攻撃者が正規のファイルと同じMD5ハッシュを持つ悪意のあるファイルを作成できれば、検出されずに一方を他方に置き換えることができます。これにより、MD5はセキュリティに敏感なアプリケーションには不適切になります。

MD5を使用すべき場合

暗号学的弱点にもかかわらず、MD5は非セキュリティ目的には依然として有用です:

クイックヒント: パスワードハッシュ化、デジタル署名、またはセキュリティが重要なアプリケーションにはMD5を使用しないでください。代わりにSHA-256またはbcryptを使用してください。

SHA-1: 進化と現状

SHA-1(セキュアハッシュアルゴリズム1)は、NSAによって開発され、1995年にNISTによって公開されました。160ビット(20バイト)のハッシュ値を生成し、より大きな出力サイズによりMD5よりも高いセキュリティを提供します。

SHA-1は、SSL証明書、Gitバージョン管理、デジタル署名など、多くのセキュリティアプリケーションの標準となりました。しかし、MD5と同様に、理論的な脆弱性が最終的に実用的な攻撃となりました。

技術仕様

コード実装

import hashlib

def get_sha1_hash(input_data):
    """入力文字列からSHA-1ハッシュを生成"""
    return hashlib.sha1(input_data.encode()).hexdigest()

# 使用例
text = "hash this string"
hash_result = get_sha1_hash(text)
print(f"SHA-1: {hash_result}")
# 出力: 3c3a3c22c0e8e8c8e8c8e8c8e8c8e8c8e8c8e8c8

# 複数のアルゴリズムの比較
def compare_hashes(text):
    """アルゴリズム間でハッシュ出力を比較"""
    return {
        'MD5': hashlib.md5(text.encode()).hexdigest(),
        'SHA-1': hashlib.sha1(text.encode()).hexdigest(),
        'SHA-256': hashlib.sha256(text.encode()).hexdigest()
    }

results = compare_hashes("example")
for algo, hash_val in results.items():
    print(f"{algo}: {hash_val}")

SHAttered攻撃

2017年2月、GoogleはSHAtteredと呼ばれる最初の実用的なSHA-1衝突攻撃を発表しました。研究者は同一のSHA-1ハッシュを生成する2つの異なるPDFファイルを作成し、SHA-1が実際には衝突耐性がないことを実証しました。

この攻撃には、約6,500 CPU年と110 GPU年という膨大な計算リソースが必要でしたが、SHA-1衝突が実現可能であることを証明しました。これにより、主要な組織はセキュリティが重要なアプリケーションでSHA-1を非推奨にしました。

現状と使用状況

主要なブラウザは2017年にSHA-1 SSL証明書の受け入れを停止しました。コミットハッシュに歴史的にSHA-1を使用していたGitは、SHA-256に移行しています。しかし、SHA-1はレガシーシステムや重要でないアプリケーションで依然として使用されています。

今日のSHA-1の許容される使用例には次のものがあります:

SHA-256: 現代の標準

SHA-256はSHA-2ファミリーの一部で、NSAによって設計され、2001年に公開されました。256ビット(32バイト)のハッシュ値を生成し、現在、実用的な攻撃が知られていない暗号学的に安全なものと考えられています。

SHA-256は、ブロックチェーン技術からSSL/TLS証明書、パスワードハッシュ化(適切なソルト付き)、デジタル署名まで、セキュリティが重要なアプリケーションの業界標準となっています。

技術仕様

コード実装

import hashlib

def get_sha256_hash(input_data):
    """入力文字列からSHA-256ハッシュを生成"""
    return hashlib.sha256(input_data.encode()).hexdigest()

# 使用例
text = "hash this string"
hash_result = get_sha256_hash(text)
print(f"SHA-256: {hash_result}")
# 出力: 8e35c2cd3bf6641bdb0e2050b76932cbb2e6034a0ddacc1d9bea82a6ba57f7cf

# ソルト付きパスワードハッシュ化(基本例 - 本番環境ではbcryptを使用)
import os

def hash_password_sha256(password):
    """ランダムソルトでパスワードをハッシュ化"""
    salt = os.urandom(32)  # ランダムな32バイトのソルトを生成
    pwd_hash = hashlib.sha256(salt + password.encode()).hexdigest()
    return salt.hex() + pwd_hash

def verify_password_sha256(stored_hash, password):
    """保存されたハッシュに対してパスワードを検証"""
    salt = bytes.fromhex(stored_hash[:64])
    stored_pwd_hash = stored_hash[64:]
    pwd_hash = hashlib.sha256(salt + password.encode()).hexdigest()
    return pwd_hash == stored_pwd_hash

プロのヒント: SHA-256は安全ですが、特にパスワードハッシュ化には、ブルートフォース攻撃に対して遅く耐性があるように設計されたbcrypt、scrypt、またはArgon2などの専用アルゴリズムを使用してください。

SHA-256が安全な理由

SHA-256のセキュリティは、いくつかの要因から来ています:

実世界のアプリケーション

SHA-256はインターネット全体の重要なインフラストラクチャを支えています:

並列比較

これらのアルゴリズム間の違いを理解することで、プロジェクトに関する情報に基づいた決定を下すことができます。包括的な比較は次のとおりです:

機能 MD5 SHA-1 SHA-256
出力サイズ 128ビット 160ビット 256ビット
We use cookies for analytics. By continuing, you agree to our Privacy Policy.