# 資訊安全導論 [台科大鄭欣明老師的線上課程](https://courses.openedu.tw/courses/course-v1:SP+104SCI004219+105/course/)的筆記。 contributed by <[`kaeteyaruyo`](https://github.com/kaeteyaruyo)> ###### tags: `Information Security System` ## CH 1 - 資訊安全定義 * 資訊安全的目的:保障我們的資產不要受到未授權的使用 * 資訊安全的三個要素 * 資產:要保護的東西(換句話說也就是可能受攻擊的目標) * 資安需求:資產需要被保護到什麼地步/達到哪些特性 * 攻擊者:意圖偷取資產的未授權者 * 資產的四個部分 * 硬體:資訊勢必被放在某台電腦上,所以要保護資訊就要保護硬體 * 軟體:資訊需要透過軟體來存取,所以軟體也得要受保護 * 資訊:資訊本人當然是保護的目標 * 通訊:傳遞資訊的過程當中也需要受保護,免得資訊洩漏或損毀 * 資安需求的 CIA 金字塔 * 保密性 (Confidentiality):資訊不會被未授權者揭露 * 舉例:出遊時把機票拍照上傳到網路上,被有心人士讀取上面的條碼而得到登機權限。資訊應該被保密而沒有被保密,違反保密性需求 * 完整性 (Integrity):避免資訊被更改或是被更改時會被察覺 * 舉例:Mozilla 的官網被攻擊,上面的下載連結被竄改,導致許多人沒辦法下載到正確的瀏覽器。資訊被修改了但是沒有人發現,違反完整性需求 * 可用性 (Availability):想使用資訊時就要隨時可以使用 * 舉例:台北燈會期間 ubike 系統故障,導致七個小時沒辦法租借單車。資訊系統應該要隨時可以使用卻沒辦法使用,違反可用性需求 * 攻擊者模型 * 完美的防禦方式是不存在的,因為我們 * 資源不足 * 無法抵擋不知道的攻擊,因此在關注範圍以外的部份,我們會假設是安全的 * 風險:攻擊發生的機率和其造成的影響之總和 * 攻擊者的三個面向 * 能力:攻擊者是主動入侵或被動監聽等 * 資訊:內在攻擊者會持有比外在攻擊者多的資訊 * 資源:單一攻擊者/情資單位/國家政府規模的資源量是不同的 * 要保護的資產 + 資安需求的程度 = 攻擊者模型 * 我的系統安不安全? => 我的系統有沒有強大到可以**保護我的資產**,在某種**攻擊者模型**底下,達到**特定的資安需求**? * 在攻擊者模型之外的攻擊者是有可能存在的 * 舉例:你有一台腳踏車,你設想攻擊者模型是攻擊者會把沒有上鎖的腳踏車偷走,所以你用了一個很好的鎖把前輪綁在車架上。結果有一個攻擊者把前輪卸下之後,剩下的部份全部搬走了 * 好的攻擊者模型,能夠包含多種攻擊、符合實際情況、攻擊真的發生時造成的影響在可接受範圍內 * 資安的心態:思考系統是否有漏洞 * 一般的工程師思考如何讓系統可以正常運作,資安工程師思考如何使攻擊失敗 => 要怎麼攻擊?(以犯罪者角度思考) * 資訊系統的強度,是跟整個系統裡面**最不安全**的那個元件的安全強度一樣的(短板效應),而**人**往往是資安系統裡面最不安全的環節 * 很多攻擊者會應用心理學進行攻擊,其使用的程度不亞於利用技術進行攻擊 => 社交工程 (Social Engineering) * 因此設計安全系統時,必須考慮「人」的因素 ## CH 2 - 對稱式加密之古典加密演算法 * 在資料傳輸的過程當中,我們需要維護資料的保密性,其中最常用的方法就是透過**加密** * 加密演算法可以分成兩大類 * 對稱式加密(祕密金鑰加密):傳輸者和接收者共享一把祕密金鑰,加密和解密都用這把祕密金鑰進行 * 非對稱式加密(公開金鑰加密):傳輸者和接收者擁有各自的公開金鑰和私有金鑰,傳輸者利用接收者的公開金鑰加密,接收者利用私有金鑰解密 * 對稱式加密演算法 [![](https://hackmd.io/_uploads/SJsLD_Qpp.png)](https://www.geeksforgeeks.org/symmetric-cipher-model/) * 定義以下變數: * 明文 m (Message / Plaintext) * 密文 c (Cipher) * 金鑰 k (Key) * 加密演算法 E (Encryption) * 解密演算法 D (Decryption) * 加密模型: c = E(k, m) * 解密模型: m = D(k, c) * 之所以叫「對稱式」,是因為加解密模型是一個可逆的函式,因此安全性的核心在於不能讓攻擊者知道金鑰 * [柯爾霍夫原則 (Kerckhoffs's principle)](https://zh.wikipedia.org/zh-tw/%E6%9F%AF%E5%85%8B%E9%9C%8D%E5%A4%AB%E5%8E%9F%E5%89%87):一個安全的加密系統,必須公開加密演算法,才能稱之為安全的系統(除了金鑰以外的細節都被人家知道,還是能保障加密性,才能叫安全) * 暴力破解法 (Brute force):將所有可能的金鑰組合試過一次,直到解出正確的明文 * 因為暴力破解法理論上可以破解所有的加密演算法,所以在定義資訊安全的強度上需要分成以下兩種安全性來討論: * 無條件安全性 (Unconditional Security):無論擁有多少資源、耗費多少時間,都無法破解 * 計算的安全性 (Computational Security):雖然能夠用暴力破解法來破解,但需要付出的資源和時間大到對攻擊者來說沒有意義 ### [替換加密法 (Substitution Cipher)](https://zh.wikipedia.org/zh-tw/%E6%9B%BF%E6%8D%A2%E5%BC%8F%E5%AF%86%E7%A0%81) * 將明文中的每一個字母用另一個字母取代,產生出密文的加密演算法 * [**凱薩加密法 (Caesar cipher)**](https://zh.wikipedia.org/zh-tw/%E5%87%B1%E6%92%92%E5%AF%86%E7%A2%BC):又稱為位移加密法 (Shift cipher)。將明文中的字母偏移固定的**偏移量(金鑰)** 得到密文,因此只要反向偏移回來就能解密 * 由於英文字母只有 26 個,因此金鑰的值必定在 0 - 25 之間,最多只要嘗試 26 種不同偏移量就能找出原文,用電腦計算非常容易就能以**暴力破解法**來破解 * 在還沒有電腦可以用的年代,**字頻分析法**也是很常用來破解凱薩密碼的方式。因為英文中有母音和子音的區別,每一個英文字母出現在常用的英文用詞中的頻率是不一樣的,因此只要知道明文中每個英文字母出現的頻率,再分析密文中的字母出現的頻率,相互對照就能找出加密用的偏移量 * [**單字母加密法 (Monoalphabetic cipher)**](https://zh.wikipedia.org/zh-tw/%E6%9B%BF%E6%8D%A2%E5%BC%8F%E5%AF%86%E7%A0%81):凱薩密碼的變體,不使用偏移量,而是固定將明文中的字母不重複地對應到另外一組字母集,因此**金鑰就是對應表** * 因為是不重複對應,以英文有 26 個字母來說,總共會有 $26! \approx 2^{88}$ 種對應表可能性,也就是說金鑰的長度大約是 $2^{88}$,相較於凱薩密碼更難以暴力破解法來破解 * 由於字母是一對一對應,所以明文中的字母頻率會原封不動地對應到密文的字母上,因此無法抵擋字頻分析攻擊 * [**維吉尼亞加密法 (Vigenere Cipher)**](https://zh.wikipedia.org/zh-tw/%E7%BB%B4%E5%90%89%E5%B0%BC%E4%BA%9A%E5%AF%86%E7%A0%81):又稱為 Polyalphabetic cipher。結合凱薩密碼與單字母加密法的特點,選擇**一個字串作為金鑰**,將此字串擴展到跟明文一樣長之後,以字串中每一個字的編碼作為位移量,將相同位置的明文字母以凱薩密碼的方式進行位移,最後得到密文 * 由於明文字母與密文字母一一對應的關係被打破,因此難以使用頻率攻擊來進行破解 * 為了要讓金鑰和明文一樣長,我們使用重複金鑰的方式來擴展金鑰的長度,如果攻擊者得知了金鑰的長度,其實還是有可能可以推敲出明文的字頻 * **自動金鑰加密法 (Autokey Cipher)**:為了在擴展金鑰長度的時候避免重複金鑰的問題,在原本選定的金鑰後面直接接上明文,作為新的金鑰,如此一來金鑰一定可以涵蓋明文的長度。由於金鑰是自動從明文產生的,因此叫作自動金鑰加密 * 因為金鑰跟明文內容直接相關,因此加密不同的明文,就會產生出不同的金鑰 * 但是因為金鑰和明文還是有關聯性,因此還是會有被推敲出原文的可能性 * **Vernam Cipher**:自動金鑰的變形,原本利用明文當作金鑰的部份用隨機不重複的字串取代。因為金鑰和原文毫無關聯,因此降低了透過金鑰推敲出明文的可能性 * 既然選定金鑰後面不足長度的部份都可以產生隨機字串了,幹嘛還需要原本選定的金鑰?就直接生成一串跟原文一樣長的隨機字串不就好了嗎? * [**One-Time Pad (OTP) 加密法**](https://zh.wikipedia.org/wiki/%E4%B8%80%E6%AC%A1%E6%80%A7%E5%AF%86%E7%A2%BC%E6%9C%AC):綜合以上,我們發現最安全的金鑰具有 (1) 金鑰和明文一樣長、(2) 金鑰的產生是隨機的,與明文獨立、(3) 金鑰只使用一次這些特性。同時具有這些特性的加密法,稱為 One-Time Pad (OPT) 加密法 * 因為金鑰只使用一次,所以我們可以偽造出多種不同的金鑰 * 由於金鑰會改變,因此密文不帶有任何資訊,用暴力破解法來窮舉的話,會得到很多組有可能性的明文,增加了密碼分析的難度 * OPT 使用時困難的部份 * 金鑰是隨機產生的(所以只能用一次) * 金鑰只能讓傳輸者與接收者知道 :::info :memo: **二戰期間的一次性密碼本** 由於 OTP 加密法需要有跟明文一樣長的隨機字串,而且這些字串又只有傳輸者跟接收者可以知道,在沒有電腦的年代,這是非常不實用但是很安全的加密方法。在二戰時期,美國軍方為了使用這樣的加密法進行傳輸,他們分給特務或是資訊兵一本**一次性密碼本**,要傳輸訊息時,就使用約定好的某一頁上的內容來進行加密,加密完之後就把那一頁撕掉,來達到使用很長的、隨機性的密文,並且只一次性使用的效果。 ::: ### [置換加密法 (Transportation Cipher)](https://zh.wikipedia.org/zh-tw/%E7%BD%AE%E6%8D%A2%E5%BC%8F%E5%AF%86%E7%A0%81) * 不是將明文的字母改變,而是將明文字母的順序重新排列來產生密文的加密演算法 * [**籬笆加密法 (Rail Fence Cipher)**](https://zh.wikipedia.org/zh-tw/%E7%B1%AC%E7%AC%86%E5%AF%86%E7%A2%BC%E6%B3%95):將明文以 **k 列的高度(金鑰)** 進行 Z 字排列,再將排好後的文字一列一列重新組合起來,以得到密文。以下圖為例:明文為 WEGOTOKTVATTHREEPM,加密後變成 WTVHPEOOTATREMGKTE ![image](https://hackmd.io/_uploads/Hy3eBnmaT.png) * **列移位加密法 (Row Transposition)**:先決定一串**隨機字串(金鑰)**,令該字串長度為 k,則將明文以 k 個一組換行,排成數列,然後依照隨機字串中,字母編號由小到大的順序,將該字母所對應到的那一行文字一一讀出,產生密文。以下圖為例:金鑰為 CONLAB,明文為 WEGOTOKTVATTHREEPM,加密後變成 TTPOTMWKHOAEGVEETR ![image](https://hackmd.io/_uploads/HynEK3m6a.png) * **排列加密法 (Permutation Cipher)**:先決定一組長度為 k 的**位置跟位置的對應關係(金鑰)**,然後將明文以 k 個一組換行,排成數列,再以新的位置順序一列一列讀出,產生密文。以下圖為例:金鑰為 431625,代表原本在順序 1 的字必須排到順序 4;原本在順序 2 的字必須排到順序 3... 以此類推。明文為 WEGOTOKTVATTHREEPM,加密後變成 GTEWOOVTTKTAEPRHME ![image](https://hackmd.io/_uploads/BJuj5hQap.png) * **積加密法 (Product Cipher)**:置換加密法沒有改變明文字母,因此字頻的問題並沒有解決。但置換加密法在現代的加密演算法當中依然很有用,這是因為**現代的加密演算法通常會混合使用多種加密方式**,例如:先將明文以置換加密法弄亂順序後,再使用位移加密法抽換字母;或是連續執行兩次置換之後,再執行兩次位移等等。這種交替利用位移加密與置換加密法的加密演算法,稱為積加密法 ## CH 3 - 對稱式加密之近代加密演算法 * [**Codebook Cipher**](https://en.wikipedia.org/wiki/Codebook):將一本充滿 codewords 的書作為金鑰,其內容可以將每一個**字詞**(不是字母)對應到五位數的數字 * 字詞與數字是多對一的關係,因此在不知道 codebook 怎麼使用的情況下,此類密文是很難破譯的 * 也因此,Codebook cipher 的安全性是建立在這本書只能被傳送者與接收者知道的前提之上 * 由於英文詞也是有詞頻的差異,因此還是有可能利用詞頻分析來猜出部份字詞。為了避免這個問題,可以搭配使用 Additive book(一本充滿隨機亂數的書),把加密後的數字再加上這些隨機數,讓結果更難破譯 * 在 Codebook 中,每一個詞對應到的數字是固定的,但是如果每一次加上 Additive book 中不同頁不同行開始的數字,就會加密出不同的密文,這讓安全性更大幅提升 * [**Enigma 密碼機**](https://zh.wikipedia.org/zh-tw/%E6%81%A9%E5%B0%BC%E6%A0%BC%E7%8E%9B%E5%AF%86%E7%A0%81%E6%9C%BA):如果這麼大本的 codebook 和 additive book 都可以當成金鑰傳送了,何不直接把可以自動進行這個加密流程的機器送給接收者,讓整個加密的過程更自動化?於是二戰時,德軍就發明了 Enigma 密碼機,利用旋轉盤和複雜的電路,以 codebook cipher 的原理做出了能夠自動加解密的機器,用在軍情的傳輸 * Enigma 密碼機用起來就像一台打字機,每按下一個按鍵就會產生出該字母對應的密文字母,但因為按下去之後內部的電路會帶動旋轉機旋轉,所以連續按兩個同樣字母會產生出不同的密文,以此達到一對多的效果 * Enigma 密碼機依賴一本密碼本來進行設定,使得解密工作可以正確進行。這本密碼本每個月會製作一次,用來選擇這月每天 Enigma 的旋轉盤、設定旋轉盤以及接線板 * [**克勞德·夏農**](https://zh.wikipedia.org/zh-tw/%E5%85%8B%E5%8A%B3%E5%BE%B7%C2%B7%E9%A6%99%E5%86%9C)提出了關於資安系統非常重要的兩個相關概念,被廣泛運用在現今的加密系統上: * **混淆 (Confusion)**:模糊化明文與密文之間的關係 * **擴散 (Diffusion)**:將明文的統計特性散佈到密文 * 進入數位化時代後,資料不再是 26 個英文字母,而是由 0101 組成的二進位資料。因此**在探討現代的加密演算法時,我們會以二進位的形式定義明文、密文與金鑰** ### [**串流加密法 (Stream Cipher)**](https://zh.wikipedia.org/zh-tw/%E6%B5%81%E5%AF%86%E7%A0%81) * 針對串流明文來加密,為 one-time pad 加密法的擴展 * OTP 加密需要產生跟明文一樣長的金鑰,這會造成在實務上有以下困難: * 為了讓接收者可以將密文解密,我們需要先以保密的方式將金鑰傳輸給接收者。那既然都可以安全地傳輸一個跟明文一樣長的金鑰了,幹嘛不直接用這種方式傳輸明文就好了? * 當資料一直來的時候,是沒有辦法產生跟明文一樣的長的金鑰的 * 為了解決以上問題,串流加密法設法使用一個較短的金鑰來生成**金鑰串流 (key stream)**,並以這個金鑰串流來跟明文進行加密,以達到 OTP 的效果 * 此金鑰串流如同 OTP 來被使用,因此也必須要保障此串流有不重複性,才能達到安全的效果 * 在千禧年左右,串流加密法非常盛行。因為其實作簡單,可以透過硬體有效率地實作,在當年 CPU 效能還不是很高的時候,很適合用專有硬體來實作串流加密 * 現今的個人電腦 CPU 效能都已經很不錯了,因此在個人電腦或是更高運算能力的電腦中,串流加密已經不再流行。但未來 IoT 系統即將興起,對於這些運算能力同樣低落的設備來說,使用串流加密會是一個很好的選擇 * 在古典密碼學中,我們常使用到對字母編碼加上一個數字後取模數的運算。==該運算作用在二進制資料上時,相當於拿明文與密鑰進行 XOR 運算(為什麼?)==,因此可以使用硬體來高效率地實作。 * 將明文與金鑰 XOR 過後得到密文,而拿密文與同一串金鑰進行 XOR 就會再度得到明文 * [**A5/1 加密法**](https://zh.wikipedia.org/zh-tw/A5/1):被用在 GSM 行動通訊系統當中,透過移位暫存器來實作 * [**RC4 加密法**](https://zh.wikipedia.org/wiki/RC4):透過變換查表的內容來實作 ### [**區塊加密法 (Block Cipher)**](https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81) * 將明文切成一個一個區塊,以區塊為單位來加密,為 codebook 的擴展 * 把資料切成數個固定大小的區塊 (block),每個區塊裡頭的位元數量是一樣多的(例如 64 bits 的區塊或是 128 bits 的區塊),然後像 codebook 一樣透過類似查表的方式,將每一個區塊的明文分別加密,產生同樣大小的密文 * 在區塊加密法中,我們使用**循環函數 (Round function)** 進行加密,將每一輪的金鑰與前一輪加密得到的結果當作輸入,計算過後得到此輪的輸出,重複這個過程數次,最後得到密文 * **區塊加密法的安全性取決於循環函數的複雜程度** * [**費斯妥密碼 (Feistel cipher)**](https://zh.wikipedia.org/zh-tw/%E8%B4%B9%E6%96%AF%E5%A6%A5%E5%AF%86%E7%A0%81):並不是一種特定的加密演算法,而是區塊加密實作方法的通用架構 1. 把明文 $m$ 切成左半邊 $L_0$ 和右半邊 $R_0$,即 $$ m = (L_0, R_0)$$ 其中底標 0 代表這是第 0 回合的輸入 2. 對於第 $i = 1, 2, \dots, n$ 輪,將前一輪的右半邊作為本輪的左半邊,而本輪的右半邊則透過將前一輪的左半邊與「前一輪右半邊和子金鑰輸入循環函數的計算結果」進行互斥或運算得出。即 $$ \begin{align} L_i &= R_{i-1} \\ R_i &= L_{i-1} \oplus F(R_{i-1}, K_i) \end{align} $$ 其中,$F()$ 函數為循環函數,$K_i$ 為第 i 輪的子金鑰(subkey) 3. 在重複 $n$ 輪的運算後,其計算結果即為密文,也就是 $$c = (L_n, R_n)$$ 4. 解密時,將所有步驟倒著做即可 * [**資料加密標準 (Data Encryption Standard, DES)**](https://zh.wikipedia.org/zh-tw/%E8%B3%87%E6%96%99%E5%8A%A0%E5%AF%86%E6%A8%99%E6%BA%96) * (發展的歷史蠻有趣的,可以去 Wiki 看) * 是一種應用了費斯妥密碼的區塊加密法,參數如下: * 區塊的長度為 64 bits * 選定的金鑰長度為 56 bits * 加密輪數為 16 輪 * 每一輪的子金鑰長度為 48 bits * 其使用的循環函數相對簡單,但因為引入了**置換盒 (Substitution box, S-box)** 的機制,因此保障了安全性 * DES 演算法基本上遵守費斯妥架構,其中的循環函數部份包含以下步驟(詳細內容到 Wiki 看圖比較快): 1. 擴張:將 32 bits 的半塊擴張成 48 bits 2. 混合:把這 48 bits 的產物和同樣 48 bits 的子金鑰進行互斥或運算 3. S盒:將上一步的產物切成 8 個 6 bits ,然後分別查表(這個表就是 S-box)把 6 bits 換成 4 bits,產生 32 bits 的結果。這個步驟是 DES 加密法非線性的來源,大幅增加了安全性 4. 置換:將上一步的產物透過固定的 P 置換進行重組 * DES 每一輪當中所使用的子金鑰,使用了金鑰排程的演算法生成(詳細略) * [**Triple DES (3DES)**](https://zh.wikipedia.org/zh-tw/3DES) * DES 最大的弱點在於金鑰長度只有 56 bits,實在太短了,在現今的計算資源底下已經無法達到 computational security,因此我們希望可以對 DES 進行一些簡易的修改,來增加他的安全性 * 3DES 簡單來說就是**使用三把不同的金鑰**,對明文連續執行三次 DES 來得到密文 * 但是其步驟並不是對明文進行連續的三次加密,而是**用第一把金鑰進行加密、第二把金鑰進行解密,再用第三把金鑰進行加密**,這樣的作法是為了跟只支援傳統 DES 的系統相容所設計的,當接收方只支援 DES 時,可以將三把金鑰都選定成同一把,那麼前兩個步驟互相抵消,就相當與只用第一把金鑰加密了一次,接收方就能只用一把金鑰進行解密,不需要將 DES 和 3DES 分成兩個函式實作 * 為什麼不能只加密兩次就好呢?這是因為如果只加密兩次,要解密時我們可以利用窮舉法,將第一次加密的結果與第一次解密的結果用大量的硬碟空間儲存起來,然後比對兩者當中是否有相同的結果存在,就能用較低的時間複雜度找出兩把金鑰,也就是進行[**中途相遇攻擊**](https://zh.wikipedia.org/wiki/%E4%B8%AD%E9%80%94%E7%9B%B8%E9%81%87%E6%94%BB%E6%93%8A)。連續進行三次加密,才能確保在面臨中途相遇攻擊時,依然需要 $2^{112}$ 次的嘗試才能以暴力破解法解密 * 3DES 的三把金鑰有三種選擇方式: * $k_1 \neq k_2 \neq k_3$:方案一,三把金鑰都不同,總共需要 56 * 3 = 168 bits 長度的金鑰。可以有效抵禦中途相遇攻擊,安全性最高,是現今被廣為採用的作法 * $k_1 = k_3 \neq k_2$:方案二,第一次加密和第三次加密使用同一把金鑰,只需要 56 * 2 = 112 bits 長度的金鑰。同樣可以抵禦中途相遇攻擊,但是面對選擇明文攻擊與已知明文攻擊的防禦強度較弱,因此現在已經棄用 * $k_1 = k_2 = k_3$:等同於只用 DES 加密一次,強度較弱,現在已經棄用 * [**進階加密標準 (Advanced Encryption Standard, AES)**](https://zh.wikipedia.org/zh-tw/%E9%AB%98%E7%BA%A7%E5%8A%A0%E5%AF%86%E6%A0%87%E5%87%86) * 90 年代之後,美國國家安全局需要強度更高的加密標準,因此公開徵求了下一個世代的加密演算法,AES 便是這次徵稿的產物。其演算法不同於 DES,不再遵循費斯妥架構,而是採用代換-置換網路,因此安全性也大大地提升,是現今最流行的對稱式金鑰加密法 * AES 的參數如下: * 區塊的長度為 128 bits * 選定的金鑰長度為 128、192 或 256 bits * 加密輪數為 10、12 或 14 輪(視乎金鑰長度而定) * AES 的加密過程是在一個 4x4 的矩陣上運作的,也就是將 128 bits 的資料先切成 16 個 bytes,再每 4 個 bytes 一列排列而成 4x4 的矩陣 * 在 AES 的每一輪當中,會進行以下四個步驟: 1. SubBytes: 類似 DES 的 S-box,將每一個 bytes 查表代換,是 AES 演算法的核心。其替換函式是一個非線性但是可逆的函式,因此安全性很高,卻又可以輕易的解密 2. ShiftRows: 將第 i 列的每一格往左循環位移 i 格 3. MixColumns: 將每一行作線性轉換 4. AddRoundKey: 將每一格與該輪的子金鑰做互斥或運算 * [**區塊加密的工作模式 (mode of operation)**](https://zh.wikipedia.org/zh-tw/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F):上述的 DES 和 AES 都是針對單一一個區塊進行加密的演算法,但實際上我們在傳輸檔案時一定不可能只會有一個區塊,如果我們需要將要傳輸的檔案完整加密的話,我們就需要先把該檔案切成數個區塊,分別進行區塊加密後,再進行傳輸。區塊加密的工作模式決定了 (1) 加密不同區塊時使用的金鑰是否相同 (2) 最後長度不足的塊要如何進行填充 (padding) * **電子密碼本 (Electronic codebook, ECB)** * 對於每一個區塊,使用一模一樣的金鑰和加密方式進行加密 * 優點是不需要一直產生與傳輸新的金鑰,並且每一個區塊的加解密是可以同步進行的 * 缺點是同樣的明文會被加密成同樣的密文,因此可能可以透過密文的長相大概猜出明文的含意(例如:許多通訊協定的標頭可能都是一樣的,會加密出一樣的密文;又或是加密圖片時,加密後的樣子依然會有原本圖片的輪廓),而且在區塊抵達順序有誤時可能會解出有意義但和原文完全不同意思的明文 (cut and paste attack) * **密碼塊連結 (Cipher-block chaining, CBC)** ![](https://hackmd.io/_uploads/rJ4qw4UTa.png) * 每一個區塊在進行加密前,先與前一個區塊加密後的密文進行互斥或運算,而第一個區塊則與一個**初始化向量 (Initialization Vector, IV)** 進行互斥或運算(類似 Additive book 的概念),使得每一個區塊的密文都與前一個區塊的內容相依,以解決 ECB 中明文與密文一對一對應的問題 * 優點是明文或初始向量只要有一點點的變化,都會造成後面的密文大幅地改變;在解密時如果有傳輸錯誤,只會影響到相鄰的區塊 * ==缺點是依然無法抵禦剪下貼上攻擊(可能要去找 ref)== ## CH 4 - 非對稱式加密 * 對稱式密碼學的特色 * 核心在於如何讓雙方共享密鑰(密鑰必須只有通訊雙方得知,一旦曝光,整個加密動作就沒用了) * 加密與解密的演算法是相同的函式 * 優點:速度快、安全、廣泛被使用 * 缺點:金鑰散佈的不合理、金鑰管理複雜(有 N 個人要互相傳輸,每個人都需要有 N-1 把金鑰耶) * 非對稱式加密的概念:把共享的祕密分成公開金鑰 $K_B$ 和私密金鑰 $K_{B^{-1}}$ * 使用非對稱加密進行傳輸的管道很像是一個人家裡的信箱:所有人都可以投信進去,但是只有信箱擁有者可以把信箱打開看裡面的內容 * 非對稱式加密的流程(令傳輸者為 Alice,接收者為 Bob) 1. Bob 必須先把自己的公開金鑰 $K_B$ 公告在網路上,讓所有要傳送資訊給他的人得知 2. Alice 要傳輸資料前,先把資料用 Bob 的公開金鑰加密,然後再傳送,也就是 $$c = E_{KB}(m)$$ 4. Bob 接收到資料後,使用他的私人金鑰 $K_{B^{-1}}$ 進行解密,也就是 $$m = D_{KB^{-1}}(c)$$ * 非對稱式加密和對稱式加密的差異 * 由於所有人要傳送給同一個接收者時,都是用同一把公開金鑰加密的,所以金鑰的管理就會變得很輕鬆:每個人只需要公開自己的公開金鑰、管理自己的私人金鑰這兩把鑰匙就可以了 * 由於金鑰是公開的,因此加解密用的函數必須要更為複雜,而且不可以是一樣的函數。我們通常會使用**單向函數**(加密很簡單、解密沒有金鑰很困難)來設計非對稱加密演算法 * 由於加解密的函式變複雜了,因此非對稱式密碼學的加解密速度,在同樣的安全性下,是比對稱式加密還要慢上 1000 倍的 * 雞尾酒式的資安防護:由於不同的演算法有不同的特性,我們不太可能用單純一種演算法就做到全面的防護。因此我們會混用各種不同密碼學的特性,來滿足不同的資安需求 * 在傳輸大量資料的時候,由於非對稱式加密比較慢但是金鑰比較好管理,因此可以使用非對稱式加密來加密對稱是加密用的金鑰,把這把金鑰傳送給接收者後,接下來的大量資料再以對稱式加密的方式進行傳輸 * [**模運算 (Modular Arithmetic)**](https://zh.wikipedia.org/zh-tw/%E6%A8%A1%E7%AE%97%E6%95%B8) * 「$X$ 除以 $N$ 取餘數」這個運算,可以表記成 $X \text{ mod } N$ * 對於除以相同的 $N$ 會得到一樣餘數的數字們,我們稱為「同餘」。若 $a$ 是 $b$ 除以 $N$ 的同餘,可以表記為 $a \equiv b \text{ (mod } N \text{)}$ * 模運算就是指將數字經過運算的結果全部對應回他們除以 $N$ 的同餘,使得運算得出的結果會周而復始地落在 $[0, N-1]$ 範圍內的運算方式 * 模運算有以下運算定律 * 加法:$(X + Y) \text{ mod } N = [(X \text{ mod } N) + (Y \text{ mod } N)] \text{ mod } N$ * 減法:$(X - Y) \text{ mod } N = [(X \text{ mod } N) - (Y \text{ mod } N)] \text{ mod } N$ * 乘法:$(X \cdot Y) \text{ mod } N = [(X \text{ mod } N) \cdot (Y \text{ mod } N)] \text{ mod } N$ * 加法反元素:$[(-a \text{ mod } N) + (a \text{ mod } N)] \text{ mod } N = 0$,所有 $-a$ 的同餘都是 $a$ 的加法反元素 * 乘法反元素:$[(b^{-1} \text{ mod } N) \cdot (b \text{ mod } N)] \text{ mod } N = 1$,所有 $b^{-1}$ 的同餘都是 $b$ 的乘法反元素。因為模運算都是作用在整數上,因此這裡的乘法反元素並不會是分數,而是使得上述等式關係成立的整數。**只有在 $b$ 與 $N$ 互質的時候,$b \text{ mod } N$ 的 $b$ 才會有乘法反元素**(如果 $b$ 和 $N$ 不互質,代表 $b$ 的因數裡面有 $N$,則 $(b \text{ mod } N) = 0$,任何數乘上 0 都是 0,此時不論 $b^{-1}$ 是什麼都不可能讓等號右邊變成 1) * [**尤拉總計函數 $\varphi(n)$ (Euler's totient function)**](https://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0):在小於等於 n 的正整數中,與 n 互質的數字個數。例如:由於小於等於 4 的正整數當中,1 和 3 與 4 互質,因此 $\varphi(4) = 2$ * 對於所有的質數 $p$ 來說,由於小於等於 $p$ 的 $p$ 個數字裡面只有他自己沒有和自己互質,所以 $\varphi(p) = p - 1$ * 若 $p$ 和 $q$ 互質,則兩數乘積的 $\varphi$ 函數值會等於兩數各自的 $\varphi$ 函數值相乘,即 $\varphi(pq) = \varphi(p)\varphi(q) \text{ for } p \bot q$ ([使用中國剩餘定理可以證明](https://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0#%E7%A9%8D%E6%80%A7)) * [**尤拉定理 (Euler's totient theorem)**](https://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%AE%9A%E7%90%86_(%E6%95%B0%E8%AE%BA)):若 $a$、$N$ 各為正整數,且 $a$ 和 $N$ 互質,則 $$a^{\varphi(N)} \equiv 1 \text{ (mod }N\text{)}$$ * [**RSA 加密法**](https://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95) * 目前最泛用的非對稱式加密演算法。RSA 是三個發明者的姓名首字母縮寫 * RSA 加密法應用了**質因數分解** $N = pq$ 這個單向函數作為安全性的核心。當 $p$, $q$ 是兩個很大很大的質數時,要從 $p$, $q$ 乘出 $N$ 是很容易的,但是在不知道 $p$ 或 $q$ 其中一者的情況下要倒推出 $N$ 是誰乘出來的是非常困難的 * **生成公鑰與私鑰** 1. 首先選定兩個很大很大的相異質數 $p$ 和 $q$,並令 $$N = pq$$ $N$ 將會被用來當作**加密時要用的除數** 2. 計算 $\varphi(N)$ 並(為了少寫一點字)令其為 $r$。由於 $p$ 和 $q$ 都是質數,根據尤拉總計函數的上述特性,$$ r = \varphi(N) = \varphi(p)\varphi(q) = (p - 1)(q - 1)$$ $r$ 將會被用來當作**生成金鑰時要用的除數** 3. 接著生成一對金鑰。先找出一個正整數 $e$,滿足 $e < r$ 且與 $r$ 互質,然後再找出一個 $d$,滿足 $$ed \equiv 1 \text{ (mod } r \text{)}$$ 也就是找出 $e$ 的模運算乘法反元素(只有在 $e$ 和 $r$ 互質時,$e$ 關於模 $r$ 才會有乘法反元素)。實務上我們通常會找小於 $r$ 的正整數中與 $r$ 互質的最小正整數來當作 $e$ 4. 令 $(e, N)$ 為公開金鑰,$(d, N)$ 為私密金鑰,然後銷毀 $p$ 和 $q$ 的紀錄 * **加密與解密訊息** * 若想要將明文 $m$ 加密為密文 $c$,需計算 $$c = m^e \text{ mod } N$$ * 若要將密文 $c$ 解密回明文 $m$,則計算 $$m = c^d \text{ mod } N$$ * RSA 的正確性證明(懶得打字了自己看) ![](https://hackmd.io/_uploads/HkM0iH5aT.png) * [**迪菲-赫爾曼金鑰交換 (Diffie–Hellman key exchange, D-H)**](https://zh.wikipedia.org/zh-tw/%E8%BF%AA%E8%8F%B2-%E8%B5%AB%E7%88%BE%E6%9B%BC%E5%AF%86%E9%91%B0%E4%BA%A4%E6%8F%9B) * 是一個可以在不安全的通道上讓通訊雙方安全地建立起一個對稱式加密用的金鑰的協定(不是用來做加密或簽名用的協定或演算法),目前被廣泛應用在許多通訊協定當中,例如 SSH、TLS 和 IPSec * D-H 協定應用了[**離散對數問題**](https://zh.wikipedia.org/zh-tw/%E7%A6%BB%E6%95%A3%E5%AF%B9%E6%95%B0) $x = g^k \text{ mod } p$ 這個單向函數作為安全性的核心。給定一個數字 $g$、一個質數 $p$ 和 $g$ 的指數 $k$,可以很輕易地算出 $x$,但是只有給定 $g$, $p$ 和 $x$,卻很難倒推出 $k$ 是多少 * **D-H 協定的運作流程** ![](https://hackmd.io/_uploads/SJ74icnaT.png) 1. 傳輸者 Alice 先選定一個很大很大的質數 $p$,然後再選定一個生成元 (generator) $g$,這個 $g$ 必須滿足對於每一個 $x \in \{1, 2, \dots, p-1\}$,一定都有 $n$ 可以使得 $x = g^n \text{ mod } p$(也就是 $g$ 在經過計算後必須要可以湊出 $p$ 以內的任意一個正整數) 2. 接著 Alice 選擇一個隨意的正整數 $a$,計算出 $A = g^a \text{ mod } p$,然後將 $g$, $p$, $A$ 三個資訊透過公開的通道傳遞給接收者 Bob 3. 收到訊息的 Bob 同樣選擇一個隨意的正整數 $b$,計算出 $B = g^b \text{ mod } p$,然後將 $B$ 回傳給 Alice 4. 由於 Alice 有 $a$ 和 $B$,Bob 有 $b$ 和 $A$,兩個人都可以用自己手上的資訊算出 $K = g^{ab} \text{ mod } p$ 的值,因此兩人就可以使用 $K$ 當作接下來進行對稱式加密時使用的金鑰 * 在 D-H 的運作過程中,$g$, $p$, $A$, $B$ 是會在公開的通道上傳輸的,大家都可以看得到的資訊,但由於離散對數問題,只知道這些資訊是很難推出 $a$ 和 $b$ 的,也因此攻擊者很難透過公開資訊推得用來計算共享祕密 $g^{ab} \text{ mod } p$ 所需的指數值,D-H 因而是一個安全的密鑰交換協定。另外,為了保證產生出來的共享祕密不會被暴力破解,我們應該要選擇一個很大的 $p$,才能讓金鑰的長度足夠長 * 雖然 D-H 對於竊聽有抵抗性,但是由於這是一個不包含身份認証的協定,因此傳輸者其實無法確認自己到底是跟誰建立起了一個共享祕密。在這樣的情況下,D-H 很容易會遭受到**中間人攻擊 (Man-in-the-Middle attack)**。攻擊者並不打算解密出 $a$ 和 $b$,而是直接在傳輸的通道中間,告訴 Alice 自己是 Bob,告訴 Bob 自己是 Alice,然後用自己選定的數字 $c$ 來跟傳輸雙方分別建立起共享祕密。由於 D-H 沒有身份認証的機制,因此 Alice 和 Bob 會誤以為自己正在跟彼此通訊,但實際上傳輸的訊息全部都可以被攻擊者給解密 * [**數位簽章 (Digital Signature)**](https://zh.wikipedia.org/zh-tw/%E6%95%B8%E4%BD%8D%E7%B0%BD%E7%AB%A0) * 非對稱式密碼學除了可以在保密性上面提供很好的保障,也可以用來保證傳輸行為的**不可否認性 (non-repudiation)**,也就是在訊息上面加上只有傳輸者才知道的一些資訊,讓接收者可以認証這條訊息絕對是透過該傳輸者所送出的(傳輸者不能否認那條訊息是他自己傳的)。我們可以透過**數位簽章**來達到這樣的功能 * 數位簽章的概念 * **簽名**:利用**非對稱式密碼學中,私有金鑰全世界只有傳輸者自己一個人知道**這樣的特性,把私有金鑰的資訊結合在傳輸者所傳出去的明文當中,藉此達到簽名的效果 * **驗章**:在接收者收到訊息時,可以透過傳輸者的公開金鑰反向解開簽名,若解開的結果跟明文一致的話,就能確保這條簽名真的是由傳輸者所送來的 * 以 RSA 實作數位簽章的流程 1. 傳輸者先使用**傳輸者的私密金鑰**對明文 $m$ 進行加密,得到簽章 $s$ 2. 傳輸者接著使用**接收者的公開金鑰**對明文 $m$ 進行加密,得到密文 $c$ 3. 傳輸者將前兩個步驟產生的結果串接在一起,得到 $(c, s)$,傳送給接收者 4. 接收者收到訊息後,使用自己的私密金鑰將密文 $c$ 解密,得到明文 $m$;再用對方的公開金鑰對簽名 $s$ 進行解密,得到 $m'$ 5. 如果 $m = m'$,就代表這個訊息真的是由傳輸者送來的 ## CH 5 - 完整性、隱私與攻擊範例 * 雜湊函數 * 訊息認証碼 MAC * 密碼安全 (待補充)