【加密 / 解密】凱撒大帝與希特勒的祕密
余憶童稚時,女生們很流行在上課的時候傳紙條,討論著學校中的八卦 (現在應該都是用Line傳了吧?),當然也怕被老師發現,也怕被偷看或加上幾筆,這些中間人的忠誠度就很顯得很重要了,如果傳輸的路線經過風紀股長的眼前,或者有一個是Spy,馬上就出包被打手心了,我記得還有一個傳情書的女同學被抓到,還被當眾唸出來,真的太可怕了啊…離題了,其實網路上有許多寫得很好的加解密文章,這裡只是要簡單的記錄一下訊息傳輸資訊安全,與一些有趣的歷史過程而已…
物理防偽
明朝官銀
在中國古代的話,在官銀下方都有官方的鑄印的,是個省的稅收,財政收入,加上當時本來鑄銀本就不是一般尋常百姓能夠做到的,所以要偽造也不是件簡單的事,只有在熔化重鑄的時候動手腳,這也是「火耗」一詞的由來…
中國古代聖旨
話說中國古代的聖旨也是有防偽的,加上官印跟特殊的墨水、紙張材料,讓聖旨保存得更久,在清朝更有以滿文、漢文雙書寫的防偽措施…
宋朝交子
再說說中國的銀票,尤於是紙張,相對於銀子來說,偽造就容易的多了,在宋朝就出現世界最早正式發行的紙鈔「交子」,而假鈔也隨之誕生,而其防偽技術首先從紙張開始下手,當時選定「川紙」作為印鈔專用紙,跟一些在紙鈔上還會採用複雜的人物圖案、特殊暗記、隱密題號等,防偽的技巧其實跟現代也是有異曲同工之巧,其實之前有個以偽鈔為題材的電影 - 無雙,有空可以去看看…
物理加密
歐洲火漆
大家應該常常在古典的歐美劇中看過,用蠟封口信件的影片吧?等待凝固前緊緊蓋刻有紋章徽記等圖案的金屬印章於上,看起來很有美感…它其實叫做火漆,又稱封蠟(sealing wax)等,是歐洲傳統用於封口信件或瓶口的一種蠟材料,往往易熔化、具有黏性並且熔化後迅速凝固。主要用松脂、石蠟等加以顏料製成,它本來也是用來防偽的,到了現代也變成了只是裝飾而已…
武俠小說
一般在武俠劇,常常都會不小心發現一紙無字天書,然後用火烤一烤,紙上就會浮現出文字,這其實也是一種加密技術,利用隱型墨水 - 檸檬汁加熱碳化的特性,還有其它的配方可以使用,像之前很流行一種叫擦擦筆的筆,也是類似的原理…
電視影集
像是很古早的電視影集虎膽妙算 - Mission Impossible的磁碟自動銷毀,算是加密經典 - 『若您的手下在行動中遭逮補或殺害,本當局將會一概予以否認,本磁碟在五秒鐘後自動銷毀,祝你好運,龍頭!』,銷毀了,就什麼都看不到了嘛…
資訊加密
凱撒密碼 - Caesar ciphers
凱撒密碼是個相當簡單的加密技巧,就是將字母移動幾個位數,比如:A->D / B->E,向右移動3位;解回來時候,就是:D->A / E->B,向左移回3位… 大家也許會想說,這也太不安全了吧?不過凱撒當時大部分敵人都是目不識丁的,所以有理由相信它是安全的…
加解密的過程就如圖所示…
這裡附上簡單的Swift實現程式碼,大家可以試一下看看…
// MARK: - 常數
final class Constant: NSObject {}
/// 凱撒密碼
enum CaesarCiphersType {
case encrypt // 編碼
case decrypt // 解碼
}
}
// MARK: - String (function)
extension String {
/// [凱撒密碼 - 簡單實現](http://junkor.me/2015/02/10/Caesar-Cipher.html)
/// - Parameters:
/// - plainText: [String](https://blog.csdn.net/weixin_48103837/article/details/130005832)
/// - function: (UInt32) -> UInt32
/// - Returns: String
static func _caesarCiphers(plainText: String, function: (UInt32) -> UInt32) -> String {
let scalars = Array(plainText.unicodeScalars)
let encrypted = scalars.map { character in
let unicode = Unicode.Scalar(function(character.value)) ?? Unicode.Scalar(0)!
return Character(unicode)
}
return String(encrypted)
}
/// [凱撒密碼](https://zh.wikipedia.org/zh-tw/凱撒密碼)
/// - Parameters:
/// - index: 位移
/// - type: 編碼 / 解碼
/// - Returns: String
func _caesarCipher(with index: UInt32, type: Constant.CaesarCiphersType) -> String {
switch type {
case .encrypt: return Self._caesarCiphers(plainText: self) { $0 + index }
case .decrypt: return Self._caesarCiphers(plainText: self) { $0 - index }
}
}
}
恩尼格瑪密碼機 - Enigma
恩尼格瑪密碼機,最著名的是二次世界大戰納粹所使用的軍用版本,算是凱撒密碼的加強版,加上以區塊來計算,比起凱撒密碼全部都單純移動同一區塊要安全的許多,但相傳它最終被艾倫·圖靈 - 人工智慧之父所被破解,也加速造成了希特勒敗北的事實,而且也間接改變了原子彈的投放對象,有關於它的相關歷史背景,大家可以去看看模仿遊戲這部電影,裡面敘述的很傳神…
加解密的過程就如圖所示…
XOR加密
算是數位時代開始的加密方式,XOR位元運算子,它的特性就是兩個值不一樣才會有輸出,XOR做兩次會回到原來的輸入值,正好適合做加解密的功能,不過正因這個『特性』,同樣的已知明文跟密文,也是可以解出密鑰的…
加解密的過程就如圖所示,它的確是超級難解的,因為原始字串多長,加/解密字串就多長,而且密鑰只用一次,就算用超級電腦算,也是要解到天荒地老啊,真的算是超完美加密,但是…有一好沒兩好,傳輸量硬生生是多了一倍…
DES - 資料加密標準(Data Encryption Standard)
由IBM於1977年發布DES,可以說是『對稱密鑰加密塊密碼演算法』的始祖,為後來的AES(進階加密標準 - Advanced Encryption Standard)打下基礎,就是『加密解密用同一個金鑰』,加上了『混淆與擴散』的工程手法,有效解決了XOR密鑰過長的問題…不過DES現在已經不是一種安全的加密方法,主要因為它使用的56位金鑰過短,有興趣的話論文在此。
非對稱加密
了解了對稱加密 - Symmetric Encryption之後,會發現它的加解密的密鑰是同一個,在廣大的網路上傳輸很容易被偷走,除非是面交,不然十分危險,所以後來才發展出了非對稱加密 - Asymmetric Encryption…
非對稱加解密的流程
主要就是把加密用的Key,複製一份給他人,也就是所謂的公鑰 - Public Key,就算公鑰被偷走也是解不開密文的,也許有人會問說,在壓縮 / 解壓縮檔案的時候,還可以讓密碼不是同一個啊? 要了解這個神奇的過程,請參考歐拉函數與模反元素…
中間人攻擊
所謂的中間人攻擊,就有點像去7-11寄貨,中間再轉給貨運公司,再轉給送貨員,再轉給管理員,最後才轉到您的身上,雖然都打包裝箱了,但中間什麼時候會被動手腳也不知道,所以才產生了CA機構…
數位憑證頒發機構 (CA - Certificate Authority)
即然有所謂的中間人攻擊,那何不找個公正的第三方機構來當中間人呢?有點像樂透開獎時,找個律師或會計師,公正的第三方人士,共同見證一下,利用再次使用非對稱加解密的功能,做二次加解密,就算中間被中間人拿到,也是解不開的…
如果中間有任何一步不對,或者是自簽憑證 (自己當CA),就會出現這樣子的頁面了…
後記
主要寫這篇的原因是,因為之前產生自簽憑證,或是.p12的時候,完全就是照著圖片做,雖然做出來了,能動,但完全不知道在做什麼,我想,在貼搜尋到的程式碼時,常常會有這種現象吧,所以才寫了這篇筆記,雖然有些內容理解的不是很完整、正確,但是還是增長了一些知識,正所謂『書到用時方恨少,事非經過不知難』,雖然本身IQ不高,也非名校出身,但慢慢的學習也是總有一天會學會的;這篇主要不是介紹加解密的演算法,反而注重在提升傳輸安全性的過程,一切的進步都是模仿前人的智慧,修正前者的缺點而來,絕非一蹴可及,持續學習才是硬道理…