SHAとは
SHA(Secure Hash Algorithm)は、NSA(米国国家安全保障局)が設計し、NISTが標準化した暗号学的ハッシュ関数のファミリーです。任意の長さのデータを固定長のハッシュ値(ダイジェスト)に変換し、データの完全性検証、デジタル署名、パスワード保存などに使用されます。
SHAファミリーには、SHA-1(160ビット、非推奨)、SHA-2(SHA-256、SHA-384、SHA-512など)、SHA-3(Keccak系、SHA3-256/SHA3-512、SHAKE128/256)があります。現在はSHA-256が最も広く使用されており、ビットコインなどのブロックチェーンのProof of Work計算や、Git(オブジェクトIDにSHA-1を歴史的に使用しSHA-256移行が進行中)、TLS証明書の署名アルゴリズムなど、インターネットインフラの基盤技術として組み込まれています。
暗号学的ハッシュ関数として実用に耐えるためには、以下の3つの性質を満たす必要があります。
- 原像計算困難性(Preimage Resistance):ハッシュ値 h からそれを生成した元データ m を逆算することが計算量的に不可能であること。
- 第二原像計算困難性(Second-Preimage Resistance):あるデータ m1 が与えられたとき、同じハッシュ値になる別のデータ m2 を見つけることが困難であること。
- 衝突困難性(Collision Resistance):任意の2つの異なるデータ m1、m2 が同じハッシュ値を持つ組み合わせを見つけることが困難であること(誕生日攻撃の観点から、n ビット出力の場合およそ2の(n/2)乗回の試行が必要とされます)。
SHA-1はこのうち衝突困難性が実用レベルで破られたため非推奨・使用禁止となっており、SHA-2以降のアルゴリズムでは現時点でこの3性質が維持されていると評価されています。
仕組み・詳細解説
マークル・ダンガード構造とメッセージパディング
SHA-1およびSHA-2ファミリー(SHA-256、SHA-512等)は、いずれも「マークル・ダンガード構造(Merkle-Damgård construction)」という設計に基づいています。これは、入力メッセージを固定長のブロックに分割し、圧縮関数(compression function)を使って先頭ブロックから順に内部状態(ハッシュ値)を更新していく構造です。処理の流れは次の通りです。
- 入力メッセージの末尾に「1」ビットを1つ追加し、続けて「0」ビットでパディングする。
- パディング後、メッセージ長を表す64ビット(SHA-256の場合)の値を末尾に付加し、全体をブロックサイズ(SHA-256は512ビット、SHA-512は1024ビット)の倍数に揃える。
- ブロックごとに圧縮関数を適用し、前のブロックの出力(内部状態)を次のブロックの入力として引き継ぐ(チェイニング)。
- 最終ブロックの処理後の内部状態が、最終的なハッシュ値(ダイジェスト)として出力される。
この構造の特性上、同じ内部状態から続けて別のデータを追記した場合のハッシュ値を、元データを知らなくても計算できてしまう「length extension attack(長さ拡張攻撃)」という弱点が理論上存在します(後述のメリット・デメリットで解説)。
圧縮関数の内部処理(SHA-256の例)
SHA-256では、初期ハッシュ値として8個の32ビットワード(最初の8個の素数の平方根の小数部分から導出された定数)を用意し、各512ビットブロックに対して64ラウンドの処理を行います。各ラウンドでは、以下のような論理演算・ビット演算の組み合わせが使われます。
- Ch(Choose)関数、Maj(Majority)関数:3つのワード間でビットごとの選択・多数決を行う非線形関数。
- Σ0、Σ1(シグマ関数):ワードを複数パターンで右ローテート(巡回シフト)した結果をXORで合成する拡散処理。
- メッセージスケジュール(message schedule):512ビットの入力ブロックを64個の32ビットワードに拡張する処理。SHA-1ではこの拡張が単純なXORのみで行われていたため線形性が残り、これがSHA-1の衝突攻撃(後述のSHAttered攻撃)を可能にした設計上の弱点の一つとされています。SHA-2ではこの拡張処理にも非線形なシグマ関数が使われ、線形性が排除されています。
この64ラウンドの計算を経て内部状態を更新し、初期値とのモジュラー加算(mod 2^32)を行うことで、雪崩効果(入力の1ビットの変化が出力全体の約50%のビットに影響する性質)を生み出しています。SHA-512は同様の構造を64ビットワード・80ラウンドで処理するため、SHA-256より1ラウンドあたりの処理データ量が多く、64ビットCPU上ではSHA-256より高速に動作するケースがあります。
SHA-3(Keccak)のスポンジ構造という設計思想の違い
SHA-3はSHA-1/SHA-2とは全く異なる「スポンジ構造(sponge construction)」を採用しています。これはSHA-2に将来重大な脆弱性が発見された場合の保険として、NISTが2007年から2012年にかけて公開コンペティションを実施し、ベルギーの研究チームが設計した「Keccak」アルゴリズムを標準化したものです。スポンジ構造は次の2フェーズで構成されます。
- 吸収フェーズ(absorbing):1600ビットの内部状態(5×5の64ビットレーン配列)に、入力メッセージをブロック単位でXORしながら取り込み、Keccak-f[1600]という24ラウンドの置換関数を繰り返し適用する。
- 絞り出しフェーズ(squeezing):内部状態から必要な長さのビット列を出力として取り出す。SHA3-256は「rate(吸収に使う幅)」1088ビット・「capacity(安全性を担保する隠し部分)」512ビットという構成になっている。
Keccak-f内部の1ラウンドは、θ(シータ)・ρ(ロー)・π(パイ)・χ(カイ)・ι(イオタ)という5つのステップ変換で構成されます。マークル・ダンガード構造を使わないため、SHA-3はSHA-2が持つlength extension attackの弱点を根本的に持ちません。またSHA-3から派生した可変長出力関数SHAKE128/SHAKE256は、鍵導出やパディングが不要な用途で近年利用が広がっています。
SHAファミリーの比較
| アルゴリズム | 出力長 | 安全性 | 用途 |
|---|---|---|---|
| SHA-1 | 160ビット | ❌ 衝突攻撃可能 | 使用禁止 |
| SHA-224 | 224ビット | ✅ 安全 | 出力長を短縮したい組込み用途 |
| SHA-256 | 256ビット | ✅ 安全 | TLS、Bitcoin、コード署名 |
| SHA-384 | 384ビット | ✅ 安全 | TLS 1.3の一部Cipher Suite |
| SHA-512 | 512ビット | ✅ 安全 | 高セキュリティ用途、鍵導出 |
| SHA-512/256 | 256ビット | ✅ 安全 | length extension attack耐性を持たせたい用途 |
| SHA3-256 | 256ビット | ✅ 安全 | SHA-2とは異なる設計(スポンジ構造) |
| SHA3-512 | 512ビット | ✅ 安全 | SHA-2代替の高強度用途 |
| SHAKE128/256 | 可変長 | ✅ 安全 | 可変長ダイジェストが必要な用途 |
SHA-384やSHA-512/256は、内部的にはSHA-512と同じ64ビット・80ラウンドの処理を行いながら、初期値を変えて出力の一部を切り詰める「トランケーション(truncation)」という手法で作られています。これにより、SHA-512と同じ内部計算コストのまま、目的に応じた出力長を得られる設計になっています。表中の「SHA-512/256」は特にHTTP/2や一部のブロックチェーン実装で、length extension attackを避けつつ256ビット出力が欲しい場合の選択肢として使われます。
AIエンジニアとしての実体験
AIエンジニアとして、SHAは様々な場面で使用します。学習データの整合性チェック、モデルファイルのバージョン管理、APIトークンの生成などで活用しています。
# ファイルのSHA-256ハッシュを計算
sha256sum model.pt
# OpenSSLでハッシュを計算
openssl dgst -sha256 model.pt
# Pythonでハッシュを計算
python3 -c "import hashlib; print(hashlib.sha256(open('model.pt','rb').read()).hexdigest())"
# Pythonでのハッシュ計算例
import hashlib
def calculate_file_hash(filepath):
sha256_hash = hashlib.sha256()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
sha256_hash.update(chunk)
return sha256_hash.hexdigest()
# 大規模モデルファイルの整合性チェック
expected_hash = "abc123..."
actual_hash = calculate_file_hash("model-7b.pt")
assert expected_hash == actual_hash, "ファイルが破損しています"
このほか、Hugging Face等のモデルハブからダウンロードしたモデルファイルの改ざん検知、Dockerイメージのレイヤーダイジェスト(Docker/OCIイメージはSHA-256でコンテンツアドレス化されている)、Gitのコミットオブジェクト(従来SHA-1、近年はSHA-256移行オプションが追加)など、SHA-256はソフトウェア開発・MLOpsの基盤技術としてほぼ意識されない形で日常的に使われています。
メリット・デメリット
メリット
- 一方向性(不可逆性):ハッシュ値から元データを復元できないため、パスワードの派生値やAPIトークンの検証用途に使える。
- 決定性と高速な検証:同じ入力からは常に同じ出力が得られ、ソフトウェア実装でも数百MB/秒〜数GB/秒規模の処理速度が出るため、大容量ファイルの整合性チェックに向く。
- 固定長出力による扱いやすさ:入力サイズに関わらず出力長が一定(SHA-256なら常に256ビット=64文字の16進文字列)なため、データベースのインデックスやキーとして扱いやすい。
- 標準化と相互運用性:FIPS 180-4/FIPS 202としてNISTに標準化されており、OpenSSL・各言語の標準ライブラリ(PythonのhashlibやNode.jsのcryptoモジュール等)で広くサポートされている。
- 雪崩効果による改ざん検知力:入力のわずか1ビットの変化でも出力の約半分のビットが変わるため、意図的な改ざんだけでなく偶発的なデータ破損の検知にも有効。
デメリット・注意点
- 高速すぎるためパスワード保存には不向き:SHA-256は高速に計算できることが逆に弱点になり、GPUやASICを使った総当たり(ブルートフォース)攻撃・レインボーテーブル攻撃に対して脆弱。パスワード保存にはbcrypt、scrypt、Argon2、PBKDF2など、意図的に計算コストを高くした専用のKDF(鍵導出関数)を使う必要がある。
- length extension attack(長さ拡張攻撃):マークル・ダンガード構造を持つSHA-256/SHA-512は、秘密鍵とメッセージを単純連結して
SHA256(secret || message)のような形でMAC(メッセージ認証コード)を作ると、秘密鍵を知らない攻撃者でも既知のハッシュ値から追加データを付加した場合の新しいハッシュ値を計算できてしまう。MAC用途では必ずHMAC構成(HMAC-SHA256など)を使うことが鉄則。 - SHA-1は既に破綻している:2017年のSHAtteredで実用的な衝突が実証されて以降、新規実装での使用は認められない。
- 量子コンピュータによる強度低下(将来リスク):Groverのアルゴリズムにより、ハッシュ関数の実効的な安全性強度は理論上半減する。ただし後述の通り、現行のSHA-256/SHA-3は当面のあいだ十分な安全マージンを持つと評価されている。
- 暗号化ではない:SHAはハッシュ関数であり暗号化アルゴリズムではないため、元データの復元(復号)はできない。データの秘匿が目的の場合はAESなどの暗号化方式を使う必要がある。
最新動向(2026年)
SHA-3の普及
SHA-3はKeccakアルゴリズムに基づき、SHA-2とは異なる内部構造を持ちます。SHA-2に脆弱性が発見された場合のバックアップとして、一部のシステムでSHA-3の採用が進んでいます。
量子コンピュータへの耐性
ハッシュ関数は量子コンピュータに対して比較的耐性があります。Groverのアルゴリズムにより実効的な強度は半減しますが、SHA-256は依然として安全と考えられています。量子耐性が特に重視される署名アルゴリズム(NISTのポスト量子暗号標準であるML-DSA/FIPS 204やSLH-DSA/FIPS 205など)の内部構成要素としても、SHA-2やSHA-3系のハッシュ関数がそのまま利用されている点は、ハッシュ関数自体の量子耐性の高さを裏付けています。
NISTの鍵長・アルゴリズム強度に関する推奨(2026年時点)
NISTはSP 800-131A(暗号アルゴリズムと鍵長の移行に関するガイドライン)の中で、ハッシュ関数についても「セキュリティ強度」という指標で推奨を整理しています。一般に、デジタル署名などの用途で112ビット以上のセキュリティ強度が求められる場合はSHA-256以上を、より長期の保護が必要な文書・アーカイブにはSHA-384やSHA-512、SHA3-384/SHA3-512の利用が推奨されます。SHA-1はあらゆる暗号用途(デジタル署名の生成、証明書発行など)で使用が認められておらず、既存システムに残るSHA-1利用箇所の棚卸しと移行が2026年時点でも継続的なセキュリティ課題として指摘されています。
ハッシュ関数を悪用したAI領域の新しい懸念
AI関連の実務では、学習済みモデルの重み(weights)やデータセットのSHA-256ハッシュをサプライチェーン検証(モデルの改ざん・すり替え検知)に使う運用が広がっています。一方で、ハッシュ値そのものは「モデルの内容が安全かどうか」までは保証しないため、ハッシュによる完全性検証と、脆弱性スキャン・出所(プロビナンス)の確認を組み合わせる運用が定石とされています。
実務ポイント(実装における注意点)
用途別の選定指針
| 用途 | 推奨アルゴリズム | 補足 |
|---|---|---|
| ファイル整合性チェック | SHA-256 | sha256sumやOpenSSLで十分 |
| デジタル署名・TLS証明書 | SHA-256以上 | SHA-1は全ブラウザ・CAで無効化済み |
| メッセージ認証(MAC) | HMAC-SHA256 | SHAを単体で秘密鍵と連結しない |
| パスワード保存 | bcrypt / Argon2 / PBKDF2 | SHA系単体は不可 |
| 長期保存が必要な署名・アーカイブ | SHA-384 / SHA-512 / SHA3-512 | より高いセキュリティ強度が必要 |
関連するRFC・標準規格
- FIPS 180-4:SHA-1、SHA-2ファミリー(SHA-224/256/384/512、SHA-512/224、SHA-512/256)を定義するNIST連邦情報処理標準。
- FIPS 202:SHA-3ファミリー(SHA3-224/256/384/512)とSHAKE128/256を定義するNIST標準。
- RFC 6234:SHAおよびSHAベースのHMAC・HKDFの実装リファレンスをまとめたIETF RFC。
- RFC 3174:SHA-1のアルゴリズム仕様を定義した初期のIETF RFC(現在は歴史的文書扱い)。
- RFC 8017(PKCS#1 v2.2):RSA署名(RSASSA-PSS等)でSHA-256等を組み合わせる際の仕様を規定。
トラブル事例と対策
⚠️ SHA-1の使用継続
症状:古いシステムでSHA-1を使用している
対策:2017年にGoogleがSHA-1の衝突攻撃を実証。すべてのシステムでSHA-256以上に移行が必要。
⚠️ パスワードの単純ハッシュ
症状:パスワードをSHA-256で直接ハッシュして保存
対策:パスワードにはbcrypt、Argon2、PBKDF2などの専用関数を使用。単純なハッシュはレインボーテーブル攻撃に脆弱。
⚠️ 自前実装のMACがlength extension attackに脆弱
症状:APIリクエストの署名検証をSHA256(secret_key + request_body)のような単純連結で自前実装している
対策:秘密鍵とメッセージの単純連結によるMAC生成はマークル・ダンガード構造の弱点を突かれ、正規の署名を知らなくても末尾にデータを追加した別の有効な署名を計算されるおそれがある。必ずHMAC-SHA256など、標準化されたHMAC構成を使用する。
関連用語
- ハッシュ関数 - SHAが属する暗号学的ハッシュ関数の総称と分類
- HMAC - SHAと秘密鍵を安全に組み合わせてメッセージ認証を行う仕組み
- bcrypt - パスワード保存に適した専用のハッシュ・KDFアルゴリズム
- デジタル署名 - SHAで作成したダイジェストに署名する仕組み
- PBKDF2 - SHAを内部で繰り返し適用してパスワードから鍵を導出する関数
- 鍵導出関数(KDF) - SHAベースのHKDF等を含む鍵生成の枠組み
- 鍵長 - ハッシュ出力長とセキュリティ強度の関係
- 耐量子暗号 - SHAの量子コンピュータへの耐性と将来の暗号移行
外部リンク・参考資料
📝 関連ブログ記事
よくある質問(FAQ)
Q. SHAとは何ですか?
SHA(Secure Hash Algorithm)はNISTが標準化したハッシュ関数ファミリーです。SHA-1(1995年、160ビット、現在廃止)、SHA-2ファミリー(SHA-256/SHA-384/SHA-512、2002年)、SHA-3(Keccak、2015年)があります。現在はSHA-256(SHA-2)が最も広く使われています。
Q. SHA-256とSHA-512はどう違いますか?
SHA-256は256ビットのダイジェスト、SHA-512は512ビットです。セキュリティ強度はSHA-512が高いですが、64ビットCPUではSHA-512はSHA-256より高速なことがあります。Webアプリ・TLSではSHA-256が標準的で十分です。SHA-512は大規模データ処理やパスワード派生関数(PBKDF2等)で使われます。
Q. SHA-1はまだ使えますか?
SHA-1は2005年以降に理論的弱点が発見され、2017年にGoogleとCWIが初の実用的衝突(SHAttered)を実証しました。TLS証明書・コード署名へのSHA-1使用は全主要ブラウザ・OS・CAが無効化しています。SHA-1は使用禁止です。レガシーシステムのSHA-1コード確認・SHA-256への移行が必要です。
Q. SHAでパスワードをハッシュ化して保存するのは危険ですか?
SHA-256やSHA-512は計算が高速であるため、単体でパスワードをハッシュ化すると、GPUやASICを使った総当たり攻撃・レインボーテーブル攻撃に対して脆弱になります。パスワード保存には、意図的に計算コストを高くしたbcrypt、scrypt、Argon2、PBKDF2などの専用KDF(鍵導出関数)を使うのが定石です。SHA系はあくまでファイル整合性検証やデジタル署名などの用途に向いています。
Q. SHAとHMACはどう関係していますか?
HMAC(Hash-based Message Authentication Code)は、SHAなどのハッシュ関数と秘密鍵を組み合わせて、メッセージ認証コードを安全に生成するための構成方法です。RFC 6234やRFC 2104で規定されており、HMAC-SHA256のように表記します。SHAを秘密鍵と単純に連結して使うと「length extension attack」という攻撃手法に対して脆弱になるため、MAC生成には必ずHMAC構成を使う必要があります。
