【加密 / 解密】凱撒大帝與希特勒的祕密

余憶童稚時,女生們很流行在上課的時候傳紙條,討論著學校中的八卦 (現在應該都是用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不高,也非名校出身,但慢慢的學習也是總有一天會學會的;這篇主要不是介紹加解密的演算法,反而注重在提升傳輸安全性的過程,一切的進步都是模仿前人的智慧,修正前者的缺點而來,絕非一蹴可及,持續學習才是硬道理…