日本語

開発者ツール · SHA ハッシュ計算ツール

SHA-256 ステップバイステップ: パディング、メッセージ スケジュール、および 64 ラウンド

· 仕組み

しゃ-256 暗号化 ブラウザ API JavaScript

メッセージ パディング、ブロック分割、64 ラウンドの処理ループ、および最終的なハッシュの組み合わせを示す図
オリジナル ToolAcre ベクトル イラスト

SHA-256 は入力をパディングし、512 ビット ブロックに分割し、それぞれを 64 回のミキシング ラウンドで実行します。この投稿では、暗号化の知識がなくても、すべての段階を平易な言葉で説明します。

バイトに実際に何が起こるのか — ほとんどの開発者が決して開かないブラックボックス

SHA-256 は、あらゆる入力を 256 ビット (32 バイト) のフィンガープリントに変換する決定論的アルゴリズムです。外側からはブラックボックスのように見えますが、実際には明確に定義された一連のステップです。これらの手順を理解すると、謎が解消され、正確さを検証し、バグを追跡し、出力がなぜそのようになるのかを理解できるようになります。アルゴリズムのすべての部分は公開されています。強さは秘密ではなくデザインから生まれます。

アルゴリズムは 512 ビット ブロックで動作します。入力が短い場合は埋め込まれます。それより長い場合は、複数のブロックに分割され、それぞれが順番に処理され、各ブロックの出力が次のブロックに供給されます。すべてのブロックが処理されると、8 つの 32 ビット数値が得られ、これらが連結されて最終的な 256 ビット ダイジェストが形成されます。

パディング — 1 ビット、ゼロ、および 64 ビットのメッセージ長を追加して、512 ビットの倍数に達するようにします。

パディング ステップは決定的で形式的です。実際の入力の後に、単一の 1 ビット (実際には、入力がバイト境界で終了する場合はバイト 0x80) を追加します。次に、512 ビットの倍数に 64 ビット不足になるまでゼロ ビットを追加します。最後に、入力長をビット単位で表す 64 ビットのビッグエンディアン エンディアンを追加します。このパディングにより、すべてのメッセージが 512 ビットの倍数であることが保証され、元の長さがエンコードされるため、異なる長さの同一の入力が同じダイジェストを生成することはできません。

入力 abc (3 バイト = 24 ビット) の場合、パディングされたメッセージは 512 ビット (1 ブロック) です。つまり、3 バイトの 61 62 63、その後に 0x80、その後にゼロ、そして24 の 64 ビット エンコード (64 ビット ビッグエンディアン フィールドの 0x00...0x18)。メッセージはちょうど 1 つの 512 ビット ブロックを埋めます。空の文字列の場合、パディングにより 0x80、その後にゼロ、その後に 0x00...0x00 (入力の 0 ビットを示す) が追加されます。 100 バイト ファイルのような長い入力の場合、パディングは最後のブロックを 512 ビットまで埋め、元の長さの 800 ビットを示します。

初期値と定数はアルゴリズムによって固定されています。それらの歴史的派生はリポジトリの証拠の外にあります

アルゴリズムは、8 つの 32 ビット作業変数から始まり、最初の 8 つの素数の平方根の小数部の最初の 32 ビットに初期化されます。これらはハードコードされた定数であり、あらゆるリファレンス実装および暗号化ライブラリのソース コードに表示されます。これらが存在するのは、数学の固定定数を使用することで、隠されたバックドアの疑いを避けることができるためです。 ToolAcre ツールはブラウザーの Web Crypto 実装を使用し、これらと同じ定数を適用します。

このアルゴリズムでは、最初の 64 素数の立方根の小数部分の最初の 32 ビットから導出された 64 丸め定数も使用されます。これらも固定されており、公開されています。定数は追加の混合材料として機能します。それらを変更すると、アルゴリズムが壊れ、異なるダイジェストが生成されます。

メッセージ スケジュール - シフトとローテーションを使用して 16 ワードを 64 に展開します

メッセージ スケジュールは、特定の式によって 16 ワード (512 ビット) を 64 ワード (2048 ビット) に拡張します。ラウンド 0 ~ 15 の場合、単語は入力ブロックから直接取得されます。ラウンド 16 ~ 63 の場合、新しい各ワードは、前の 2 つのワード (特定のオフセットで) を取得し、回転とシフトを適用し、別のワードで XOR 演算を行って、結果を保存することによって計算されます。この式は 1 つのブロックのコンテキスト内で決定的で可逆的ですが、拡張により入力の影響がすべての 64 ラウンドに広がります。

展開式では、右回転 (一方の端から落ちたビットが他方の端に再び現れる循環ビット シフト) と右シフト演算を使用します。回転ではすべてのビットが保持されますが、その位置は変更されます。右シフトはビットを破棄します。回転、シフト、XOR 演算を組み合わせることで、入力のすべてのビットがスケジュール内の複数のワードに影響を与えるようになります。

1 ラウンド — ビットミキシング操作として記述された Ch、Maj、および Sigma 関数、および 8 つの作業変数がどのように更新されるか

64 の各ラウンドは、メッセージ スケジュールの 1 ワードを処理し、8 つの作業変数を更新します。コア関数には 6 つの演算が含まれます。制御変数に基づいてビットを選択する条件付きミックス (「選択」の意味で Ch と呼ばれることが多い)、3 つの変数から最も一般的な値を選択する多数決関数 (Maj)、作業変数を回転およびシフトする 2 つの特別な混合関数 (Sigma_0 および Sigma_1)、および加算法 2^32 です。すべての算術演算は 32 ビット ワードで実行されるため、オーバーフローが発生します。

「choose」関数は 3 つの 32 ビット入力を受け取り、各ビット位置について、制御ビットが 1 の場合は最初の入力からビットを選択し、制御ビットが 0 の場合は 2 番目の入力からビットを選択します。マジョリティ関数は 3 つの入力を調べ、各ビット位置について、3 つの入力の中で最も頻繁に出現するビット値を出力します。これらは、線形性を壊し、小さな入力変化が状態全体に予測不能に伝播する非線形操作です。

ブロックをチェーンして出力を生成する — 各ブロックの結果を実行状態に追加する

各ラウンドは、8 つの作業変数を循環させ、現在のラウンド定数、メッセージ スケジュール ワード、および前の状態から計算された新しい値を組み込むことによって、すべての作業変数を更新します。最初の 7 つの作業変数がシフトします。8 番目が 1 番目、1 番目が 2 番目、というように変化します。新しい 8 番目は、混合関数を使用して古い変数から計算されます。 64 の丸め後、8 つの新しい 32 ビット値が得られます。これらは初期定数に追加され (モジュロ 2^32)、このブロックの最終ハッシュ状態が生成されます。

マルチブロック メッセージの場合、1 つのブロックの 8 つの値が次のブロックの初期状態になります。チェーンにより、入力内のどこかでの変更が後続のすべてのブロックに確実に影響します。最後のブロックに到達するまでに、入力のあらゆるビットが最終出力に影響を与えます。

実用的な例とこれでカバーされないもの — ショートメッセージのパディングとブロック数のトレース。セキュリティ証明は対象外です

入力 abc の場合、メッセージはパディング後の 1 つの 512 ビット ブロックに収まります。パディングにより 424 ビットが追加され、合計 512 ビットになります。メッセージ スケジュールでは、これが 64 語に拡張されます。各ラウンドは 1 ワードを消費し、ミキシング関数を通じて 8 つの作業変数を更新します。 64 が丸められた後、状態は初期定数と XOR 演算され、最終的なダイジェスト ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad が生成されます。

これは公開されたテスト ベクトルです。同じ入力で同じ計算を行うと、常に同じ出力が生成されます。 ToolAcre ツールは、ブラウザーの Web Crypto 実装を介してこの正確な計算を実行します。 abc をハッシュし、その結果を既知のベクトルと比較することで検証できます。 Web Crypto を正しく実装しているブラウザは同じ出力を生成します。このアルゴリズムでは、近道や代替パスは認められません。

要点: Web Crypto は秘密を公開せずに決定論的な SHA-256 ミキシングを実行します

アルゴリズムは公開されており、すべてのステップは決定的です。ミキシング関数 (Ch、Maj、Sigma_0、Sigma_1) は非線形となるように選択されています。これは、1 つの入力ビットを変更しても 1 つの出力ビットが予測どおりに変化しないことを意味します。 16 メッセージ ワードを 64 に拡張すると、入力全体が計算全体に影響を与えるようになります。 64 ラウンドと状態の連鎖は、出力が入力のすべてのビットに敏感であることを意味し、リポジトリは結果の出力を決定論的なダイジェストとして使用します。衝突耐性は制限付きのセキュリティ特性であり、出力の重複が数学的に不可能であることを保証するものではありません。

暗号の証明はこの投稿の範囲外です。重要な点は、アルゴリズムが実際に何を行うのかがわかったことです。それは魔法ではありませんし、ブラックボックスでもありません。 ToolAcre が正しくハッシュ化していることを確認したい場合は、次の手順で独自の入力をトレースするか、別の言語のリファレンス実装を使用して結果を比較します。ブラウザの実装と正しい参照は、同一の入力に対して同一のダイジェストを生成します。