まずは単一換字式暗号とは何か、軽く説明をします。
※本稿は具体的なコードは明示していません。ソースコードはGitHubに置いているので、コードを必要としている方はそちらを見た方が話が早いでしょう。
●シーザー暗号(シフト暗号)
シーザー暗号は単一換字式暗号の一種です。アルファベット表を3文字ずらすことによって暗号文を作る暗号です。ひっくるめて、文字をシフトさせて暗号文を作ることから、シフト暗号と言った方が分かりやすいでしょうか。これら暗号の種類の中では認知度は高いと思われます。
A→D
B→E
C→F…という具合に、3文字ずらす暗号です。
シーザー暗号はもとより、「n文字シフト」の「n」が復号鍵となるため、シフト暗号はアルファベットで高々26文字しか種類がないことから、最大25回のブルートフォースアタックで容易に解読され暗号強度は全く期待できません。
参考情報:シーザー暗号 - Wikipedia
●単一換字式暗号
ある文字を異なる文字に置き換えて暗号文を作る暗号です。
シーザー暗号と比べ多少複雑になりましたね。表のように、AをQに、BをAにという具合に置き換える暗号です。 *1
置き換えるタイプの暗号は、ブルートフォースアタックでは現実的に解かれることはないでしょう。最大試行回数が26*25*24……となり、よく分からない単位の恐ろしい数字が出てくる計算です。要するに、26文字のパスワードを総当りしているようなものです。アルファベットの単一換字式暗号は、アルファベット・単語(グループ)の頻出度で解析する手法が定石と思われます。また、アルファベットに限らず、ひらがな五十音でも同様です。
参考情報:単一換字式暗号 - Wikipedia
●実装する
上述の単一換字式暗号の表をそのままそっくり配列に置き換えるだけで、材料は揃います。(以下、文字表・暗号表と呼びます)
これら2つの配列を用い暗号文を複合させるには、順序とインデックス(添字)が解くポイントとなります。
“単一換字”なので文字が一対一で対応している特徴から、元の文字を特定(複合)するためには、文字を置き換える手続きの逆を行えば良いのです。例えば、暗号文「T」を複合する場合は、暗号表からTに対応するインデックスを探します。文字表から、探し当てたインデックスに対応する文字を探し、その結果がMであることから、TはMということが分かります。(プログラミング的な表現すると、暗号表配列からstring "T"に完全一致する値を検索し、そのインデックスを取得する。文字表配列からそのインデックスの値を取得する。)
表を色付けすると下記のようになります。
これが解法となり、復号処理をする大まかな流れとしては下記となります。(C#)
- 与えられたstring型の文字列(文字表と暗号表)を、ToCharArray() でchar配列にキャストします。
- [ループ処理]:与えられたstring型の暗号文の文字列を foreach (char array in text) で一文字ずつ取り出します。(開始)
- [ループ処理]:取り出された文字を、Array.IndexOf() で暗号表から検索し、インデックスを取得します。(暗号表に存在しない文字は -1 が返却されます。)
- [ループ処理]:取得したインデックスを使用し、GetValue() で文字表から該当する文字を取得します。
- [ループ処理]:取得した文字を複合文(というstring型の変数)に結合演算子+=で結合します。(終了)
なお、暗号化処理は結果を逆転させればいいだけなので、文字表と暗号表の配列を入れ替えるだけで、メソッドを使いまわす実装方法がスマートでしょう。Windows フォームアプリケーションであれば、変換ボタンを置いてboolean型で判定させるだけで良いと思われます。
●C#で実装したWindows アプリケーション
私が作ったモノは下記になります。
ダウンロード:Releases · reinforchu/SimpleCipherCalc · GitHub
アプリケーション起動直後はシーザー暗号のサンプルが入力された状態になっています。
使い方としては、こんな感じです。
(机上でやると面倒くさいので、CTFとかではコピペするだけで解きたいよね)
「Encryption mode」ボタンを押下すると暗号文作成モードになり、Cipher rule に従って暗号文が作れます。なお、申し訳程度の例外処理しか書いてないので、落ちる時は落ちます。
本稿で少しでも暗号に興味を持っていただければ幸いです。詳しく暗号について知りたい方は、結城 浩先生の名著『暗号技術入門 秘密の国のアリス』を一読されることをおすすめします。*2
今日の情報通信技術の機密性は様々な暗号技術によって担保されています。暗号技術を知ることは面白いと思いませんか?