本文へ移動

暗号学的ハッシュ関数

暗号学的ハッシュ関数を検証の観点から解説し、安全性、バイトエンコーディング、SHA-2、SHA-3、Keccak、ブロックチェーンでの用途、実装上のリスクを取り上げます。

更新日

教育目的の情報であり、投資または暗号技術の実装に関する助言ではありません。ダイジェストの一致だけで、真正性、所有権、承認、ファイナリティ、データ可用性が証明されるわけではありません。

要点

暗号学的ハッシュ関数は、バイト列として表されたメッセージを、定められた出力長のダイジェストへ決定論的に写像します。出力長が固定された n ビットのハッシュ関数では、基本的な関係は次のようになります。

h = H(m), where h is in {0,1}^n

同じバイト列を同じアルゴリズムに入力すれば、同じダイジェストが得られます。入力を一ビット変えると、多数の出力ビットが予測不能な形で変わることが望まれますが、この雪崩効果自体が安全性の定義ではありません。主な安全目標は、原像計算困難性(ダイジェストを与えられたとき、それを生成する入力を見つけることが現実的に不可能)、第二原像計算困難性(ある入力を与えられたとき、同じダイジェストになる別の入力を見つけることが現実的に不可能)、衝突困難性(同じダイジェストになる任意の異なる二つの入力を見つけることが現実的に不可能)です。

ハッシュ化は暗号化ではありません。復号鍵はなく、入力を復元できるという保証もありません。無限にあるメッセージ候補を有限の出力空間へ写像するため、衝突は必ず存在します。安全であるとは、選択したアルゴリズムと出力長において、利用可能な衝突を見つけることが計算上困難であるという意味です。

また、ダイジェストだけでは真正性を保証できません。ファイルのハッシュを再計算して不一致を検出できるのは、期待するダイジェストとアルゴリズムを信頼できる経路から入手した場合に限られます。プロトコルは、ハッシュを署名、メッセージ認証コード、認証済みデータ構造、コンセンサスルール、またはプルーフ・オブ・ワークと組み合わせ、より強い保証を実現します。

仕組み

  1. 正確なバイト列を定義する。 テキストエンコーディング、大文字と小文字、空白、フィールドの順序、整数表現、長さプレフィックス、シリアル化は、すべて m に影響します。プロトコルでは正規エンコーディングを定め、ハッシュを特定のアルゴリズム、バージョン、ネットワーク、用途に結び付ける必要があります。
  2. 指定された構成を実行する。 SHA-256 は長さに上限のあるメッセージを前処理してブロックに分割し、内部状態を反復的に更新します。SHA3-256 は KECCAK に基づくスポンジ構造を使用します。どちらも 256 ビットのダイジェストを返しますが、異なる関数であり、出力に互換性はありません。
  3. 必要な性質に応じて安全性を評価する。 理想的な n ビットのハッシュ関数では、汎用的な原像探索に約 2^n 回の評価が必要です。一方、誕生日効果により、汎用的な衝突探索は約 2^(n/2) 回で済みます。アルゴリズムが破られている、ダイジェストが切り詰められている、または周辺プロトコルに欠陥がある場合、出力長だけでは安全性を判断できません。
  4. ダイジェストを中心にプロトコルを構築する。 デジタル署名方式ではメッセージのダイジェストに署名できます。HMAC は秘密鍵を加えてメッセージを認証します。マークルツリーは一つのルートで多数のリーフにコミットします。プルーフ・オブ・ワークは、ダイジェストがターゲットを満たすまで候補ブロックヘッダーを繰り返しハッシュ化します。これらの構成が提供する保証はそれぞれ異なります。
  5. ブロックチェーンが指定する正確な関数を使う。 Bitcoin のブロックヘッダーとマークルノードは、指定されたバイト順で二重 SHA-256 を使用します。Ethereum の実行レイヤーが使用するのは、標準化前の KECCAK 設計による Keccak-256 であり、標準化された SHA3-256 ではありません。したがって、「256 ビットハッシュ」という表記だけでは検証に不十分です。
  6. 意味を解釈する前にコンテキストを検証する。 期待するダイジェストの出所、アルゴリズム識別子、バイトエンコーディング、ドメインまたはブロックチェーン、参照するブロックと状態、承認状況、切り詰めの有無を確認します。誤ったコンテキストで計算だけが正しくても、検証は失敗です。

具体例

  • 入力のごく小さな変更。 hello を表す五つの UTF-8 バイトの SHA-256 は 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 です。最初のバイトを大文字の H に置き換えると、185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969 になります。ダイジェストの違いから、どのバイトが変わったかを知ることはできません。
  • すべての攻撃モデルで安全強度がダイジェスト長と同じになるわけではない。 理想的な 256 ビットのハッシュ関数は、原像探索に約 2^256 の計算量を要しますが、衝突探索の計算量は 2^128 です。この違いは、デジタル署名の処理など、プロトコルが衝突困難性に依存するときに重要です。
  • マークル証明が認証するのは、一つのルートを基準とした包含関係である。 検証者は、エンコードされたリーフと提示された各兄弟ノードを指定された順序でハッシュ化し、コミットされたルートを再構成します。一致しても、そのルートがファイナライズ済みであること、リーフのデータが真実であること、省略されたデータが利用可能であることまでは証明できません。
  • プルーフ・オブ・ワークではターゲットのルールが加わる。 Bitcoin は、候補ヘッダーの二重 SHA-256 値をコンセンサスルールに従って解釈した結果が、エンコードされたターゲット以下である場合にのみ、そのヘッダーを有効と判定します。マイナーが多くの作業を行っても、ダイジェストの衝突困難性が高まるわけではありません。

リスク

  • 廃止されたアルゴリズムや用途に適さないアルゴリズムを使用すること。特に、衝突困難性が必要な場面で SHA-1 に依存すること。
  • SHA3-256、Keccak-256、SHA-256、二重 SHA-256、および切り詰め方が異なる方式を相互に置き換えられるものとして扱うこと。
  • 正規のバイト列ではなく表示されたテキストをハッシュ化したり、Unicode 正規化、空白、エンディアン、フィールド順序、長さエンコーディングを見落としたりすること。
  • ファイルと期待するダイジェストを同じ侵害済みの場所からダウンロードし、独立した完全性チェックにならないこと。
  • パスワード保存に、適切なワークファクターを備えたソルト付きの専用パスワードハッシュ方式ではなく、高速な汎用ハッシュを直接使用すること。
  • 自作の認証コードとして H(secret || message) を使用すること。一部の反復型ハッシュ構成は長さ拡張攻撃を許しますが、HMAC は鍵付き認証を目的に設計されています。
  • プロトコルの規模と脅威モデルに照らして、切り詰め後の衝突安全性と原像安全性を計算せずにダイジェストを切り詰めること。
  • ドメイン分離を行わず、複数のプロトコルでエンコーディングを使い回し、あるコンテキストで有効なダイジェストを別のコンテキストで解釈できるようにすること。
  • トランザクションハッシュが、承認、ファイナリティ、実行成功、所有権、またはチェーン再編が起こらないことを証明すると考えること。
  • コンテンツハッシュが、参照先データを取得できることまで保証すると考えること。利用可能なコピーがすべて失われても、コミットメント自体は有効なままになり得ます。
  • エクスプローラー上の文字列を比較する際に、バイト順、プレフィックス規則、シリアル化、または画面が内部識別子を異なる形式で表示している可能性を確認しないこと。
  • 標準テストベクトル、保守されているライブラリ、独立したレビュー、アップグレード手順なしに暗号プリミティブを実装すること。

よくある誤解

  • ハッシュは暗号化されたデータである。 暗号化は正しい鍵があれば元に戻せますが、暗号学的ハッシュは復号操作のない一方向のダイジェストです。
  • 異なる入力が同じダイジェストになることはない。 固定長の出力では衝突が必ず存在します。安全な設計では、その発見と悪用を現実的に不可能にします。
  • 256 ビットのダイジェストは常に 256 ビットの安全強度を持つ。 理想的な 256 ビットのハッシュ関数でも、汎用的な衝突困難性は約 128 ビットであり、プロトコルの選択によってさらに低下する場合があります。
  • ハッシュの一致から、メッセージの作成者が分かる。 単なるハッシュには秘密情報がなく、送信者を認証しません。発信元が重要な場合は、署名または適切な MAC を使用します。
  • Keccak-256 と SHA3-256 は同じ関数の別名である。 両者の設計は密接に関連していますが、標準化パラメーターが異なり、生成するダイジェストも異なります。
  • オンチェーンのトランザクションハッシュは決済を証明する。 トランザクションハッシュが識別するのはエンコードされた取引データです。チェーンへの取り込み、実行状況、承認数、ファイナリティは別々の事実です。

関連トピック

出典

ナビゲーション

Wiki を検索...