プログラミング
 Computer >> コンピューター >  >> プログラミング >> プログラミング

Blowfishアルゴリズムの仕組みとは?サブキー生成とデータ暗号化の流れを解説

Blowfishアルゴリズムの概要

Blowfish(ブローフィッシュ)は、対称鍵方式のブロック暗号アルゴリズムの一つで、一度に64ビットのデータブロックを暗号化します。Feistelネットワーク構造を採用しており、その動作手順は「サブキー生成」と「データ暗号化」という2つの段階に分けられます。

動作の2つの主要プロセス

  • サブキー生成:最大448ビット長の秘密鍵を、合計4168ビットのサブキー群へと変換するプロセスです。
  • データ暗号化:ネットワークを16回反復処理します。各ラウンドでは、鍵に依存する置換(permutation)と、鍵およびデータに依存する代入(substitution)が行われます。アルゴリズム内部の演算は32ビットワードに対するXORや加算が中心で、それ以外に必要なのはラウンドごとの4回のインデックス付き配列参照だけというシンプルな構成です。

以下、それぞれの段階について詳しく見ていきましょう。

サブキー生成

Blowfish暗号アルゴリズムは、非常に多くのサブキーを使用します。これらのサブキーは、実際にデータの暗号化や復号化を行う前に事前に生成しておく必要があります。

PアレイとSボックスの構成

Pアレイは18個の32ビットサブキーで構成されます。

P1, P2, …, P18

さらに、それぞれ256エントリを持つ32ビットのSボックスが4つ用意されています。

S1,0 〜 S1,255
S2,0 〜 S2,255
S3,0 〜 S3,255
S4,0 〜 S4,255

サブキー生成の手順

  1. 初期化:まず、固定文字列を使ってPアレイと4つのSボックスを順番に初期化します。この固定文字列には、円周率πの16進数表記の桁が含まれています。
    P1=0x243f6a88、P2=0x85a308d3、P3=0x13198a2e、P4=0x3707344 など。
  2. 鍵とのXOR:P1を鍵の先頭32ビットとXORし、P2を次の32ビットとXORする、という操作を鍵の全ビットに対して実行します(最大P14まで)。鍵のビットを使い果たしたら、先頭に戻って同じ操作を繰り返し、Pアレイ全体が鍵のビットとXORされるまで続けます。なお、短い鍵の場合は、それと等価なより長い鍵が存在することになります。たとえば、Aが64ビットの鍵であれば、AAやAAAも同一の鍵として扱われます。
  3. 全ゼロ文字列の暗号化:ステップ1とステップ2で定義されたサブキーを使用して、Blowfishアルゴリズムにより全ゼロ(オールゼロ)の文字列を暗号化します。
  4. P1・P2の更新:ステップ3の出力である64ビットの値で、P1とP2を置き換えます。
  5. 再暗号化:更新されたサブキーを使って、ステップ3の出力を再度暗号化します。
  6. P3・P4の更新:ステップ5の出力で、P3とP4を置き換えます。
  7. 反復処理:同様の手順を続け、まずPアレイのすべてのエントリを、続いて4つのSボックスの全エントリを、逐次変化するアルゴリズムの出力で順番に置き換えていきます。

必要なサブキーをすべて生成するには、合計521回の反復処理が必要です。この導出プロセスを毎回実行するのは計算負荷が高いため、アプリケーション側では生成済みのサブキーを保存して再利用することが推奨されます。

データ暗号化

Blowfishの暗号化処理は、16ラウンドからなるFeistelネットワークで構成されます。

  1. 入力は64ビットのデータ要素xです。
  2. xを2つの32ビット半分に分割します:xL と xR
  3. i = 1 から 16 まで、以下の処理を繰り返します。
    xL = xL XOR Pi
    xR = F(xL) XOR xR
    xL と xR を入れ替える
  4. 16ラウンド完了後、最後の入れ替えを打ち消すために、xL と xR をもう一度入れ替えます。
  5. 続いて、xR = xR XOR P17、xL = xL XOR P18 を計算します。
  6. 最後に、xL と xR を再結合して暗号文を得ます。

復号化は暗号化とほぼ同じ手順で行われますが、唯一異なる点は、P1, P2, …, P18 を逆順に使用するところです。

  1. C言語のシフト演算とは?左シフト・右シフト・補数の基本をわかりやすく解説

    問題 C言語を使用して、ある数値に対する左シフト・右シフト・補数(ビット反転)を求める簡単なプログラムを作成するには、どのようにすればよいのでしょうか。 解決方法 左シフト(<<) 変数の値を1ビットだけ左へシフトすると、その値は2倍になります。「a × 2」を計算したのと同じ結果です。 例:a = 10 の場合、a << 1 = 20 右シフト(>>) 変数の値を1ビットだけ右へシフトすると、その値は元の半分になります。「a ÷ 2」の整数除算と同じ結果です。 例:a = 10 の場合、a >> 1 = 5 サンプルプログラム 以下は、シ

  2. C#のコメントとは?複数行・単一行コメントの書き方を解説

    コメントは、コードの内容や意図を説明するために記述する注釈です。コンパイラはコメント部分を完全に無視するため、プログラムの動作には一切影響しません。C#では、複数行にわたるコメントは「/*」で始まり、「*/」で終わります。 複数行コメント /* 以下はC#における 複数行コメントの例です */ 「/* ... */」で囲まれた範囲はすべてコンパイラによって無視されます。処理の概要や注意点など、複数行にわたる説明を残したい場合に使用します。 単一行コメント // 変数の宣言 int a = 10; 単一行コメントは「//」から行末までがコメントとして扱われます。変数の意味や処理の意図を手軽にメモ