ヘロログ
暗号

シーザー暗号(Caesar Cipher)

シーザー暗号(Caesar Cipher)は、暗号技術の歴史において最も古く、最も有名な暗号の一つである。古代ローマの政治家・軍人であるユリウス・カエサル(Julius Caesar, 紀元前100年頃〜紀元前44年)が、軍事通信の秘匿に用いたとされる。

カエサルと暗号通信

ローマの歴史家スエトニウスの記録によれば、カエサルはアルファベットを3文字ずらす換字を用いて書簡を暗号化していた。ガリア戦争(紀元前58〜50年)では、敵のガリア人に通信内容を知られることなく味方と連絡を取るためにこの暗号が活用された。『ガリア戦記』には、包囲されたクィントゥス・キケロに宛てた暗号文の逸話も残されている。

カエサルの後継者アウグストゥスも同様の手法を用いたが、こちらは1文字ずらしで、アルファベットの末尾で循環させずにAAと表記したという。

シーザー暗号は単一換字式暗号(monoalphabetic substitution cipher)の最も単純な形であり、平文の各文字を一定数だけずらして暗号文を生成する。仕組みが極めてシンプルなため、暗号の基本概念を学ぶ出発点として最適である。

アルゴリズム

シーザー暗号は、鍵生成暗号化復号の3つのアルゴリズムから構成される。

鍵生成(KeyGen)

シーザー暗号では、ずらす文字数はn = 3に固定されている。つまり鍵は常に一つであり、鍵生成アルゴリズムは起動するとn = 3を出力するだけである。

暗号化(Enc)

アルファベットの各文字に0〜25の番号を割り当てる(A=0, B=1, ..., Z=25)。平文の文字xに対して、暗号化関数は次のように定義される。

シーザー暗号の暗号化
E(x) = (x + 3) \bmod 26

復号(Dec)

暗号文の文字yに対して、復号関数は次のとおりである。

シーザー暗号の復号
D(y) = (y - 3) \bmod 26

換字表

シーザー暗号(n = 3)の対応表は次のとおりである。平文を小文字、暗号文を大文字で表記する慣例に従う。

平文abcdefghijklmnopqrstuvwxyz
暗号文DEFGHIJKLMNOPQRSTUVWXYZABC
計算例:「hello」を暗号化する

各文字を数値に変換し、暗号化関数を適用する。

\begin{aligned} \text{h}(=7) &\to (7+3) \bmod 26 = 10 \to \text{K} \\ \text{e}(=4) &\to (4+3) \bmod 26 = 7 \to \text{H} \\ \text{l}(=11) &\to (11+3) \bmod 26 = 14 \to \text{O} \\ \text{l}(=11) &\to (11+3) \bmod 26 = 14 \to \text{O} \\ \text{o}(=14) &\to (14+3) \bmod 26 = 17 \to \text{R} \end{aligned}

よって、平文「hello」の暗号文は「KHOOR」となる。

図解

シーザー暗号の換字対応を図に示す。上段が平文、下段が暗号文で、各文字が3文字分ずれて対応している。暗号化では上から下へ、復号では下から上へ読み替える。

平文 暗号文 a b c d ... x y z D E F G ... A B C 暗号化 ↓ +3 復号  ↑ −3 図:シーザー暗号の換字対応(n = 3)

シフト暗号への一般化

シーザー暗号ではずらす文字数がn = 3に固定されているが、これを任意の数nに拡張したものをシフト暗号(Shift Cipher)と呼ぶ。シフト暗号はROTnとも表記される(ROTはRotate=回転の意)。

シフト暗号(ROTn)の一般式
\begin{aligned} E_n(x) &= (x + n) \bmod 26 \quad (n = 1, 2, \ldots, 25)\\ D_n(y) &= (y - n) \bmod 26 \end{aligned}

n = 0のとき平文と暗号文が一致してしまうため除外される。鍵空間はn = 1からn = 25までの25通りしかない。

復号の別表現

復号で左にn文字ずらすことは、右に26 - n文字ずらすことと同等である。つまり、ずらす値として26 - nを入力すれば、暗号化アルゴリズムで復号も行える。

ROT13

シフト暗号の中でも特に有名なのがROT13n = 13)である。英語のアルファベットは26文字であるため、ROT13を2回適用すると元の平文に戻るという性質を持つ。

E_{13}(E_{13}(x)) = (x + 13 + 13) \bmod 26 = (x + 26) \bmod 26 = x

この性質により、暗号化と復号に同じ操作を使える。UNIXシステムではネタバレ防止やジョークの隠蔽などにrot13コマンドが利用されてきた。

安全性と弱点

シーザー暗号(およびシフト暗号)は、現代の基準では暗号としての安全性をまったく持たない。主な弱点は以下の2つである。

総当たり攻撃(Brute Force Attack)

鍵空間がわずか25通りしかないため、すべての鍵を試すだけで解読できる。コンピュータはもちろん、手作業でも短時間で全パターンを列挙可能である。

総当たり攻撃の例

暗号文「KHOOR」に対し、n = 1から順に左シフトを試す。

n復号結果n復号結果
1JGNNQ14WTAAD
2IFMMP15VSZZC
3HELLO16URYYB
4GDKKN17TQXXA
5FCJJM18SPWWZ
6EBIIL19ROVVY

n = 3で「HELLO」という意味のある英単語が出現するため、鍵は3であると判明する。

頻度分析(Frequency Analysis)

シフト暗号では、平文中の各文字が常に同じ暗号文字に変換される。そのため、暗号文中の文字の出現頻度を調べることで鍵を推定できる。英語では「E」が最も頻出する文字(約12.7%)であるため、暗号文中で最も多い文字が「E」に対応すると仮定すれば、ずらし量が逆算できる。

歴史的な解読事例

2006年、イタリアのマフィアのボスであるベルナルド・プロヴェンツァーノが逮捕された。彼の通信にはシーザー暗号の変種(A=4, B=5, ...のように数字に置き換える方式)が使われており、その解読が逮捕の手がかりの一つとなった。

まとめ

項目内容
分類単一換字式暗号(シフト暗号の特殊ケース)
n = 3(固定)
暗号化E(x) = (x + 3) \bmod 26
復号D(y) = (y - 3) \bmod 26
鍵空間(シフト暗号)25通り
安全性極めて低い(総当たり・頻度分析で容易に解読)

シーザー暗号は単純すぎて実用的な安全性を持たないが、この弱点を克服するために、ずらし量を位置ごとに変えるヴィジュネル暗号(Vigenère Cipher)が16世紀に考案された。

実践

下のウィジェットでシーザー暗号(シフト暗号)を体験できる。ずらし量を変えて、暗号化・復号の動作を確認してみよう。

シーザー暗号エンコーダー / デコーダー

Python実装

Pythonによるシーザー暗号(シフト暗号)の実装を示す。暗号化・復号・総当たり攻撃の3つの機能を含む。

caesar_cipher.py
def caesar_encrypt(text, n):
    result = []
    for c in text:
        if c.isalpha():
            base = ord('A') if c.isupper() else ord('a')
            result.append(chr((ord(c) - base + n) % 26 + base))
        else:
            result.append(c)
    return ''.join(result)

実行例
def caesar_decrypt(text, n):
    return caesar_encrypt(text, -n)

# 暗号化
plaintext = "Hello, World!"
ciphertext = caesar_encrypt(plaintext, 3)
print(f"暗号化: {plaintext} -> {ciphertext}")

# 復号
decrypted = caesar_decrypt(ciphertext, 3)
print(f"復号:   {ciphertext} -> {decrypted}")

# 総当たり攻撃
print("\n--- 総当たり攻撃 ---")
target = "KHOOR"
for i in range(1, 26):
    print(f"n={i:2d}: {caesar_decrypt(target, i)}")
暗号化: Hello, World! -> Khoor, Zruog! 復号: Khoor, Zruog! -> Hello, World! --- 総当たり攻撃 --- n= 1: JGNNQ n= 2: IFMMP n= 3: HELLO n= 4: GDKKN ...