TOUCH THE SECURITY Powered by Security Service G

コラム

2019.08.27

暗号を振り返る ――その1 シーザー暗号

パーソルテクノロジースタッフの「Zライダー」です。

コンピューターとインターネットが普及した今の世の中では、暗号化された通信が有線無線問わず私たちの身の回りにところかまわず飛び交っています。現代は「暗号」というものが身の回りにあふれかえっている時代とも言えるかもしれません。過去の歴史において暗号とはどのようなもので、どのように人々と関わってきたのでしょうか。コンピューターも無線通信もなかった時代に使われていた暗号についていくつか調べてみたので紹介したいと思います。

1.シーザー暗号

イエス・キリストが誕生する少し前、古代ローマで活躍したガイウス・ユリウス・カエサル(シーザー)といえば誰もが知る英雄ですが、彼も暗号を使っていたことが知られています。後の歴史家スエトニウスは書物「皇帝伝」に、カエサルは各文字をそれぞれ同じ文字数だけシフトして暗号を作成したと記しており、この暗号は「シーザー暗号」と呼ばれています。

それぞれの文字を「3つ」づつずらすというルールの場合、平文の「a」→ 暗号文の「d」、「b」→「e」、「c」→「f」という具合に暗号化されていきます。「x」「y」「z」のように3つシフトすると「z」を超えてしまう場合は、次の文字は再び「a」に戻るというルールでシフトされ、それぞれ「a」「b」「c」と暗号化されました。平文が “hello” の場合、暗号文は “khoor” になるわけです。

現代の視点から見れば、このような聞くからに単純そうな暗号でカエサルさんはよく天下をとれたものだとツッコミを入れたくもなりますが、当時の人々の識字率や情報伝達手段を考えると、このような単純な暗号でも十分立派に英雄の偉業に役立ったのかもしれません。

2.Pythonで実際に復号してみる

ここで実例として、シーザー暗号の暗号文「rtytwhdhqj」の平文を導く手段を考えてみます。

暗号文がシーザー暗号であることさえ推測できれば、紙と鉛筆という原始的な手段でもある程度の時間と労力で解くことが可能ですが、コンピューターの力を借りれば一瞬で解読することが可能になります。プログラム言語Pythonで記述した以下のソースコードを実行し、文字をシフトする数の候補を1~25までを総当たりで試すことで一瞬で解読することが出来ました。

♦ソースコード

# strInputText	: シーザー暗号の暗号化/復号の対象文字列。英語小文字。
# intKey	: 暗号化キー。英語小文字アルファベットのみの場合は1-25の範囲の数値。
def caesar(strInputText, intKey):
    strResultList = []
    for char in strInputText:
        if (ord(char) + intKey) <= ord('z'):
            strResultList.append(chr(ord(char) + intKey))
        else:
            strResultList.append(chr((ord('a') – 1) + (ord(char) + intKey - ord('z'))))

    print('key:' + str(intKey) + ' > ' + ''.join(strResultList))

if __name__ == '__main__':
    for i in range(1, 26):
        caesar('rtytwhdhqj', i)

♦実行結果

key:1 > suzuxieirk
key:2 > tvavyjfjsl
key:3 > uwbwzkgktm
・・・(省略)・・・
key:20 > lnsnqbxbkd
key:21 > motorcycle <----答え
key:22 > npupsdzdmf
・・・(省略)・・・

3.アルゴリズムと鍵空間

ここでは「シーザー暗号」はなぜ単純で脆弱な暗号なのかということを整理して考えてみます。

平文から暗号文を作る手順および、暗号文を復号する手順のことを「暗号アルゴリズム」といいます。また、「暗号アルゴリズム」を実行するのに必要になる値を「暗号鍵」といいます。

暗号アルゴリズム すべての文字を暗号鍵が示す文字数分シフトする
暗号鍵 1~25までの数字 (英語アルファベット小文字のみの場合)

シーザー暗号のアルゴリズムと暗号鍵は上記のように示すことが出来ます。シーザー暗号のアルゴリズムでは、対象とする文字の種類の数しか暗号鍵のパターン数を確保することが出来ません。

暗号鍵として使用することが出来る値のパターンの総数が小さすぎるため、総当たりによる解読が容易であり、シーザー暗号はとても脆弱な暗号だということが出来ます。

暗号鍵として使用できる値のパターンの総数のことを「鍵空間」と呼びます。また、鍵空間すべてを力ずくで総当たりして解読を試みることを「ブルート・フォース・アタック」(総当たり攻撃)と呼びます。

1976年以来、標準ブロック暗号として採用されていた「DES」と呼ばれる暗号規格は56bit長の暗号鍵を使用し、実に7京2000兆パターン以上もの鍵空間を有していますが、それでも現在では技術の進歩により総当たり攻撃が可能であるため安全ではありません。そのため現在では、より強固な暗号である「AES」暗号規格が標準となっています。

4.単一換字暗号

シーザー暗号はアルゴリズムが単純すぎて、大きな鍵空間が確保できないので脆弱であることがわかりました。シーザー暗号ではすべての文字が同じ文字数の数だけ、しかも同じ方向にシフトするというアルゴリズムだったため、文字の種類の数しか鍵空間を確保できませんでした。

それでは、「文字によってシフトする数や方向が異なる」というアルゴリズムに変更するとどうなるでしょうか。例えば以下のような感じです。

  • 「a」は右に5文字シフトして「f」に変換する
  • 「b」は右に3文字シフトして「e」に変換する
  • 「c」は右に23文字シフトして「z」に変換する
  • ...(省略)...
  • 「y」は左に1文字シフトして「x」に変換する
  • 「z」は左に22文字シフトして「d」に変換する

このように平文1文字に対して暗号文1文字に変換するタイプの暗号は「単一換字暗号」と呼ばれます。シーザー暗号も単純な単一換字暗号の一種です。

文字によってシフトする文字数や方向が異なる変換リストを使用するなら、取りうる鍵空間は26 * 25 * 24 * 23 * 22 * 21 … = 実に4兆の1000兆倍という膨大な鍵空間を持つことになります。

これだけ膨大な鍵空間であれば総当たりで解読を試みるのは非現実的であり、解読は困難と思えるかもしれません。しかし実際には、ブルート・フォース・アタックではない別の方法で解読を行うことが可能です。次回は単一換字暗号を解読してみます。

5.まとめ

  • 暗号アルゴリズムとは、暗号化および復号を行う手順です。
  • 暗号鍵とは、暗号アルゴリズムを実行するのに必要となる値を指します。
  • 鍵空間とは、暗号鍵が取りうる値のパターンの総数を指します。
  • 暗号アルゴリズムが単純であり鍵空間が小さい暗号は脆弱な暗号といえます。
  • 単一換字暗号とは、平文1文字を暗号文1文字に暗号化するタイプの暗号アルゴリズムであり、シーザー暗号も単一換字暗号の一種です。
    Python実行環境
  • iPhone7 + pythonista3 (スマホ上で動作するPythonのIDE)
  • Windows10 + JetBrains PyCharm Community Edition

記事一覧に戻る