今天來講傳說中最古老的加密方法
在古羅馬時期,尤利烏斯・凱撒(Julius Caesar)是個軍事天才,但他也很怕自己的軍事命令或秘密訊息被敵人攔截。
於是他就想出了一個方法來「讓訊息變難讀」:
把每一個英文字母往後挪三個位置!
例如:A → D,B → E,C → F…
這就是歷史上第一個被記錄下來的加密方式之一,現在我們叫它:
Caesar Cipher(凱撒加密)
他的加密方式很簡單,就是將字母往後移n位(不含數字及特殊符號)
加密使用加密函數E(m) = (m+k )%26 , k為位移量
解密使用解密函數D(c) = (c-k)%26
很簡單吧:D
來看看題目會怎麼出吧~
import string
LOWERCASE_OFFSET = ord("a")
ALPHABET = string.ascii_lowercase[:16]
def b16_encode(plain):
enc = ""
for c in plain:
binary = "{0:08b}".format(ord(c))
enc += ALPHABET[int(binary[:4], 2)]
enc += ALPHABET[int(binary[4:], 2)]
return enc
def shift(c, k):
t1 = ord(c) - LOWERCASE_OFFSET
t2 = ord(k) - LOWERCASE_OFFSET
return ALPHABET[(t1 + t2) % len(ALPHABET)]
flag = "redacted"
key = "redacted"
assert all([k in ALPHABET for k in key])
assert len(key) == 1
b16 = b16_encode(flag)
enc = ""
for i, c in enumerate(b16):
enc += shift(c, key[i % len(key)])
print(enc)
這題的加密邏輯是他會先做base16編碼,然後再用key來做位移。
但因為它key固定長度為一,且範圍僅限於ALPHABET
所以我們可以透過列舉所有key來破解這題凱薩加密
import string
LOWERCASE_OFFSET = ord("a")
ALPHABET = string.ascii_lowercase[:16] # "abcdefghijklmnop"
def b16_decode(cipher):
plain = ""
for i in range(0, len(cipher), 2):
a = ALPHABET.index(cipher[i])
b = ALPHABET.index(cipher[i+1])
binary = "{0:04b}".format(a) + "{0:04b}".format(b)
plain += chr(int(binary, 2))
return plain
def unshift(c, k):
t1 = ALPHABET.index(c)
t2 = ALPHABET.index(k)
return ALPHABET[(t1 - t2) % len(ALPHABET)]
enc = "ihjghbjgjhfbhbfcfjflfjiifdfgffihfeigidfligigffihfjfhfhfhigfjfffjfeihihfdieieih"
for key in ALPHABET:
unshifted = "".join([unshift(c, key) for c in enc])
try:
decoded = b16_decode(unshifted)
print(f"[{key}] => {decoded}")
except:
continue
最後列舉出來最不像亂碼那個就是flag啦~
E(m)=αm+β (mod 26)
,其中α與β為整數,且α必須與26互質
D(c) = α^-1(c-β) (mod 26)
以上就是關於凱薩加密的內容,明天會講一些其他的古典密碼學
想看更多,歡迎明天再來ㄛ~