05 安全性演算法 === ###### tags: `Algorithm` 這篇筆記是我參考【演算法圖鑑】和網路資源所製作。如果內容有誤,還請不吝賜教! ## **目錄** [toc] ## **05-0 傳輸數據時的問題** - **竊聽 Eavesdrop** 資料可能被第三方讀取 ```sequence Note left of Alice: Info Alice->Bob:Send Data/Information Note left of Bob: Eve: Hack Data Note right of Bob: Info ``` - **竄改 Falsification** 資料被第三方擷取並竄改,或是通訊中發生不明原因而造成數據損毀,都稱為「竄改」。 ```sequence Note left of Alice: Info Alice->Bob:Send Data/Information Note left of Bob: Eve: Hack and Revise Data Note left of Bob: Data loss Note right of Bob: ???? ``` - **電子欺騙 Spoofing** 傳輸訊息的兩端用戶其中一方有可能是偽裝的駭客,稱為電子欺騙。 一般來說,電子欺騙可能有兩種情況: **(1) 接收端是駭客 -** 最常見的事件就是騙取個資 ```sequence Note left of Alice: Personal Info Alice->Eve(Bob):Send Data/Information Note left of Eve(Bob): Steal Personal Info ``` **(2) 發送端是駭客 -** 常見的情形包括釣魚網站或是可能藏有病毒的不明檔案。 ```sequence note left of Eve(Alice): (Virus)Info/File Eve(Alice)->Bob: Send File/Info note right of Bob: Receive File note left of Bob: Get Virus! ``` - **抵賴 Repudiation** 若訊息發送用戶不懷好意,在訊息送出後主張自己沒有送出該訊息,稱為抵賴。抵賴最大的問題在於**網路上契約或商業交易**不易成立,甚至會有詐騙的事件發生。 ```sequence Note left of Alice: Info Alice->Bob: Send Info Note right of Bob: Info Bob->Alice: What the hell is this message? Note left of Alice: I didn't send it! Not me! ``` 而對於這些問題,我們有以解決辦法: | 問題 | 解決方法 | |:-------- |:---------------------| | 竊聽 | 加密 | | 竄改 | 訊息鑑別碼 v 數位簽章 | | 電子欺騙 | 訊息鑑別碼 v 數位簽章 | | 抵賴 | 數位簽章 | 以下將介紹各種安全性演算法 ## **05-1 雜湊函數 Hash Function** 雜湊函數在我先前的筆記(02-Data Structure)裡有提到,摘要如下: > Hash function is a function that turns given data into a fixed-length value, called "hash code". > > Hash function has the following features: > 1. **Fixed Length of Hash Code** - No matter how massive the given data is, the length of hash code is always fixed. > 2. **Same Data, Same Hash Code** > 3. **Similar Data, Different Hash Code** > 4. **Unidirectional** - It's impossible to infer the original data from its hash code. > 5. **Hash Collision** - Different data might have the same hash > > code, when this occurs, we call it "hash collision". However, > > chances of collision are extremely slim. 雜湊函數因為它的**單向性**、**單一性**及**不可辨讀性**,被廣泛地運用在加密及製作數位簽章上。而雜湊驗算法則又有許多種,常見的有MD5, SHA-1, SHA-2等。現在大多使用SHA-2,因為MD5和SHA-1都曾有被破解的事件,存在一定的風險。 註: *MD5 - Message Digest Algorithm 5* *SHA - Securing Hash Algorithm* ## **05-2 加密 Encryption** ### **加密的基本原理** - **明文 - plain text, 可直接被解讀的訊息** 傳輸數據時若以明文直接傳輸,極有可能被第三方直接偷窺,因此數據傳輸時大多以密文的形式傳輸。 - **密文 - cipher text, 經加密後的訊息, 無法直接被電腦或人解讀** 以下解釋了明文是如何被傳輸的。 :::info **加密**(encryption)就是將明文和金鑰進行計算而產生密文 而**解密**(decryption)就是對密文和金鑰再進行運算還原成原本的訊息 ::: ```sequence Note left of Alice: Plain text Note left of Alice: Encryption Note left of Alice: Cipher text Alice->Bob: Send Cipher text Note left of Bob: Eve: Get Cipher text Note left of Bob: Eve: ??? Note right of Bob: Decryption Note right of Bob: Plain text ``` 加密的方式又可根據金鑰的性質分為兩種:**對稱加密**和**非對稱加密**。 **對稱加密**指的是雙方都使用相同的金鑰進行加密、解密,好處是運算速度非常快,但是它有一個致命的缺點 -- 安全性的缺陷。**非對稱加密**則相反,雙方使用不同的金鑰進行加密、解密,它和對稱加密是互補的 -- 一方的優點即是另一方的缺點。 | | 對稱性加密 | 非對稱加密 | |:------:|:----------:|:----------:| | 安全性 |:x:|:heavy_check_mark: | | 運算速度 |:racehorse: |:turtle:| 現在來談談對稱性加密的大問題。 假設Alice要用這種演算法傳遞訊息給Bob,顯然如果雙方都知道金鑰的話,那是一件很美好的事。問題就在於多數時候雙方先前是沒有相互往來的,意即兩方都沒有共同金鑰。這種時候,我們有以下的解決辦法: ### **共用金鑰系統 shared-key cryptosystem** Alice在傳送訊息給Bob前,要先傳送金鑰給Bob,接著再傳送密文給Bob。 ```sequence note left of Alice: abc Alice->Bob: send key note left of Bob: Eve: get key note right of Bob: key note left of Alice: encrypt note left of Alice: ??? Alice->Bob: send cipher text note left of Bob: Eve: decrypt note right of Bob: ??? note right of Bob: decrypt note right of Bob: abc ``` 共用金鑰系統其實在兩千年前就已經存在,最著名的莫過於凱薩加密系統。現今常用的為AES加密演算法。 問題來了,在傳送金鑰的過程中,金鑰還是有可能被偷窺(**金鑰傳送困難**),這不就又回到最一開始的問題了嗎?而且隨著傳輸的對象越多,管理金鑰的數量也會越來越多。這些都是共用金鑰系統最大的問題。 ### **公開金鑰系統 public-key cryptosystem** 公開金鑰系統彌補了共用金鑰系統的缺點,因為訊息只能用公鑰加密也**只能用私鑰解密**,即使公鑰和密文被偷窺,第三方也因為沒有**解密的關鍵 -- 私鑰**而無法獲取原始明文,安全性相對提升。 以下將解釋這個加密演算法是如何運作的: 1. Bob先準備兩個金鑰 -- **公鑰**和**私鑰**,公鑰可公開到網路上,但私鑰必須被保管好而不能外流。接著將公鑰傳送給Alice。 2. Alice用Bob傳來的公鑰將訊息加密。 3. Alice將密文傳給Bob。 4. Bob用私鑰來解密,得到明文。 ```sequence Note left of Alice: abc Note right of Bob: P(公鑰), S(私鑰) Bob->Alice: send P key to Alice Note right of Alice: Eve: get P Note left of Alice: encrypt using P Note left of Alice: ??? Alice->Bob: send cipher text Note left of Bob: Eve: get ??? Note left of Bob: Eve: Huh??? Note right of Bob: decrypt using S Note right of Bob: abc ``` 然而公鑰加密也有存在公鑰可信度的問題。換句話說,我們無法確定Alice是否不懷好意,又或者公鑰傳輸的過程,很有可能被第三者替換,這樣第三者便能取得訊息而雙方仍渾然不覺,稱為中間人攻擊。 以下將說明中間人攻擊的過程: 1. **Eve**製作了自己的公鑰Px和私鑰Sx。 2. **Bob**公開了他的公鑰P,但是在P傳到**Alice**之前,**Eve**攔截了這條通道,並將P改為Px。 3. **Alice**以為她收到的公鑰是**Bob**的,於是她用這隻公鑰Px加密訊息,並送出密文Tx。 4. **Eve**再度攔截,將密文用Sx解密取得明文。 5. **Eve**再用**Bob**公開的公鑰將原文加密成新密文T,再將T傳輸給**Bob**。 6. **Bob**收到密文T,用自己的私鑰S解密,但卻完全不知道**Eve**動過手腳...。 ```sequence Note left of Alice: abc note right of Eve: Px & Sx Note right of Bob: P(公鑰), S(私鑰) note left of Eve: Interrupt Bob->Eve: send P to Alice Eve->Alice: send Px to Alice Note left of Alice: encrypt using Px Note left of Alice: ??? note right of Eve: Interrupt Alice->Eve: send cipher text to Bob note left of Eve: decrypt using Sx note left of Eve: get abc note left of Eve: encrypt using P note left of Eve: ??? Eve->Bob: send cipher text to Bob Note right of Bob: decrypt using S Note right of Bob: abc ``` 這個時候,解決方案便是**數位憑證**,之後的筆記將會介紹。 ### **混成密碼系統 Hybrid Cryptosystem** 混成密碼系統是共用金鑰和公共金鑰的加強版。將金鑰再進行一次公鑰加密,使得雙方能夠安全的傳遞共同金鑰。這個方法不只兼備了共用金鑰系統的快速,更解決了**金鑰傳送困難**的問題,一舉數得。 以下將說明混成密碼系統的運作過程: 1. Alice準備共同金鑰K,並將訊息用K加密成密文T。 2. Bob利用公鑰加密的方法,讓Alice取得Bob的公鑰P。 3. Alice用P將K加密並傳送給Bob。 4. Bob用私鑰S解密,如此一來兩人都有了金鑰K。 5. Alice傳送T給Bob,Bob就可以用K解密。 ```sequence note left of Alice: abc + mutual key K note left of Alice: encrypt "abc" using K -> "???" note right of Bob: P(公鑰), S(私鑰) Bob->Alice: send P to Alice note left of Alice: encrypt K using P -> K' Alice->Bob: send cipher text K' to Bob note right of Bob: decrypt K' using S note right of Bob: get K Alice->Bob: send "???" to Bob note right of Bob: decrypt ??? note right of Bob: abc ``` :::info - **SSL憑證** 混成密碼系統最被廣泛應用的地方,就是SSL安全憑證。我們每天用電腦或手機瀏覽網站時,和遠端伺服器幾乎都是以http(HyperText Transfer Protocal, 超文本傳輸協定)傳輸資料,而SSL憑證的目的是為了確保我們的裝置(client端)和伺服器(server端)皆是安全的。大部分的時候我們都會在網址看到*https*,那個s就代表這個網站有SSL憑證,是安全的。 ::: ### **迪菲-赫爾曼金鑰交換 Diffle-Hellmen Key Exchange** #### **金鑰性質** 迪菲-赫爾曼金鑰交換所交換的金鑰有一些特殊的運算性質: 1. 兩個金鑰可以透過一些運算合成一把新的金鑰。 2. 金鑰合成並無先後順序。 3. 合成的金鑰不能被分解、還原成原來的金鑰。 #### **運作模式和安全性** 現在來看看這種交換方式是如何運作的: 1. Alice跟Bob各自準備自己的私鑰A和B。 2. 再準備一隻公鑰P。 3. 兩人各自將私鑰和公鑰合成PA和PB。 4. 兩人互相交換新合成的金鑰。 5. 兩人各自將**收到的金鑰**和**自己的私鑰**再合成一次。 6. 這樣兩人都有共同金鑰PAB了。 ```sequence note left of Alice: A & P note right of Bob: B Alice->Bob: send P to Bob note left of Alice: Combine -> PA note right of Bob: Combine -> PB Alice->Bob: send PA Bob->Alice: send PB note left of Alice: combine -> PAB note right of Bob: combine -> PAB ``` 由於Eve只可能偷取P、PA或PB,又因為這種金鑰的特性,Eve不可能合成出PAB。因此這種演算法具有高度的安全性。 ## **05-3 身分、訊息鑑別 Authentication** ### **鑑別的重要性** 傳輸訊息時可能發生好幾種狀況: 1. 即使是密文,在傳輸的過程中也會遭到惡意竄改,造成傳訊的兩方解讀有誤。這種狀況尤其在商業交易上是最不容許發生的。 ```sequence note left of Alice: abc note left of Alice: encrypt note left of Alice: ??? Alice-Eve: send ??? to Bob note right of Eve: Interrupt and Falsify note right of Eve: ?$@ Eve-Bob: send ?$@ to Bob note right of Bob: decrypt note right of Bob: xyz ``` 2. 訊息傳輸的來源無法被確定。如果訊息是由駭客送出,那收到訊息的接收端怎麼確定這個訊息是從他信任的發送端送出呢? 以下將逐一介紹解決這些問題的演算法。 ### **訊息鑑別碼 Message Authentication Code (MAC)** #### **運作過程** 1. **Alice**先將解密的金鑰$K_t$傳送給**Bob**(**公開金鑰系統** 或 **迪菲-赫爾曼金鑰交換**)。並將訊息用$K_t$加密。 2. **Alice**再準備另外一把產生MAC(訊息鑑別碼)的金鑰$K_m$,並再度用安全的方法傳送給**Bob**。 3. **Alice**將$K_m$和密文一起進行運算,得到MAC。 :::info 根據**運算過程**可將**MAC的產生方式**分成許多種,如HMAC,OMAC和CMAC。 現在普遍使用**HMAC**,它是利用**hash function**產生MAC。 ::: 4. **Alice**將密文和MAC傳送給**Bob**。 5. 和**Alice**一樣,**Bob**使用收到的$K_m$和密文一起進行相同運算得到**新MAC**。 6. **Bob**檢查新的MAC是否和**Alice**傳來的一樣,如果一樣則表示**Alice**傳來的密文沒有被竄改,並將密文用$K_t$解密。反之,**Bob**發出請求請**Alice**再傳一次直到正確為止。 ```sequence Alice-Bob: send key Kt to Bob note left of Alice: abc note left of Alice: encrypt using Kt note left of Alice: ??? Alice-Bob: send key Km to Bob note left of Alice: ??? + Km note left of Alice: = MAC Alice-Bob: send ??? and MAC to Bob note right of Bob: ??? + Km note right of Bob: = new_MAC note right of Bob: check if MAC == new_MAC note right of Bob: if don't fit... Bob-Alice: send again! note left of Alice: OK, fine. ``` #### **MAC的安全性** 如果這個時候第三方Eve想竄改任何訊息,訊息鑑別碼都能發揮作用,讓Bob能夠收到安全且正確的訊息。 1. 如果Eve竄改了密文,Bob便能在檢查的時候發現**MAC**和**新的MAC**不相符,並要求Alice再傳一次。 2. 如果Eve竄改了密文和**鑑別碼**,由於Eve並不擁有密鑰$K_m$,因此即使他變更了MAC和密文也**無法使這兩者相對應**。所以Bob還是能夠發現訊息被竄改,要求Alice再傳一次。 #### **MAC的痛點** 由於Alice和Bob手中都握有產生MAC的金鑰,雙方都能對訊息進行加密。然而這會產生一個問題。如果今天Alice或Bob不懷好意 **(比方說Alice可以主張訊息是Bob捏造的,又或者Bob可以自行製作訊息然後說這是Alice傳來的)**,這個時候因為MAC的來源沒辦法確定,造成**抵賴**的發生,這也是MAC無法解決的問題。 接下來將介紹解決抵賴的演算法 -- **數位簽章**。 ### **數位簽章 Digital Signature** #### **目的&優點** 現實生活中的簽章目的是為了確認一個人的身分,數位簽章也一樣,目的是為了確認訊息是否真的由某人發送,解決了訊息來源的不確定性。 #### **運作模式** 數位簽章的運作模式大致如下: 1. Alice先準備兩把金鑰 -- **P**(公鑰)和**S**(私鑰)。值得注意的是,訊息是用**S**加密,用**P**解密。 2. Alice先將訊息雜湊,得到hash value,並用**S**將hash value加密,產生的結果即是Alice的簽章 -- **Sign**。 3. Alice公開自己的簽章**Sign**和**P**,提供給Bob甚至是其他人查證。 4. Alice將訊息用其他加密方式傳送給Bob。 5. Bob收到訊息後,開始查證是否為Alice傳送。查證方法如下:將訊息丟進相同的雜湊函數,得到新的hash value。接下來Bob用**P**解密Alice的簽章**Sign**,還原出Alice的hash value。如果兩人的雜湊值吻合,代表訊息就是Alice傳來的。 ```sequence note left of Alice: abc note left of Alice: P and S note left of Alice: hash(abc) -> 70fc (hash value) note left of Alice: encrypt(70fc) -> Sign note right of Alice: Sign & P note right of Bob: decrypt Sign using P note right of Bob: 70fc Alice-Bob: send abc using encryption to Bob note right of Bob: hash(abc) -> 70fc (hash value) note right of Bob: check if the two hash values are the same note right of Bob: (if doesn't fit...) Bob-Alice: send again! ``` 因為數位簽章是透過私鑰**S**加密形成,加上只有Alice擁有私鑰,因次這種演算法確保了製作出來的簽章具有**唯一性**,即簽章不能夠被偽造。 #### **迷思澄清** **Q1: 數位簽章跟公鑰加密系統都有用到公私鑰的概念吔,那到底差在哪呢?** :::info 先從運作方式切入,我們會發現這兩種演算法**完全不同**。 (假設發送訊息的是Alice,接收訊息的是Bob。) (再假設公鑰是P,私鑰是S) | | 加密 | 解密 | |:--------:|:----:|:----:| | 數位簽章 | S~A~ | P~A~ | | 公鑰加密 | P~B~ | S~B~ | 完全相反的原因是因為這兩種演算法背後的**意義**截然不同。公鑰加密系統是為了**安全、不被偷窺**地傳輸訊息,而數位簽章則是**向大眾證明**訊息是由自己傳送的。兩種演算法的**目的**不同,自然就有許多差別。 (別把這兩種演算法搞混了!!!) ::: Q2: 為甚麼還要先將訊息經過雜湊,而不是直接將訊息用私鑰加密? :::info 最主要是為了**壓縮訊息**,**降低耗費時間**。 公鑰加密運算量龐大,直接用訊息進行運算非常沒效率。**雜湊函數**這時也派上用場了。因為雜湊函數可以幫我們為一筆資料產生一獨有的「身分證」 -- **雜湊值**(忽略機率極低的雜湊碰撞!),所以利用這個雜湊值產生簽章,就跟用原來的訊息一樣沒有差別。又因為相較於原本的訊息,**雜湊值的資料量極小**,因此對它進行公鑰加密速度便提升許多。 ::: #### **數位簽章的缺陷** 數位簽章其實還存在著一個問題,那就是Alice有可能是不懷好意的Eve偽裝的。根本的問題在於**公鑰本身並沒有任何證據證明公鑰製作者是安全的一方**。因此接下來我們將介紹解決這個問題的演算法 -- **數位憑證**。 ### **數位憑證 Digital Certificate** #### **目的&優點** 使用公鑰加密系統或數位簽章時,公鑰本身因缺乏認證機制而有可能被替換。而數位憑證的出現,則確保了公開金鑰的真實性。 #### **運作過程** 1. Alice想要傳送自己的公鑰P~A~給Bob。為了證明P~A~真的是Alice自己的,在此之前Alice要先向憑證機構(Certificate Authority, CA)申請憑證。 2. Alice將P~A~和自己的電子郵件一起傳送給CA。 3. 憑證機構CA確認資料無誤後,再用自己的私鑰S~C~將Alice的資料加密,產生簽章。 4. CA將這份簽章的電子檔傳送給Alice,而這份檔案就是Alice的數位憑證。 5. Alice將憑證傳送給Bob。 6. Bob收到後,利用CA公開的金鑰P~C~解開憑證。解開後Bob會獲得Alice的email和P~A~。 7. Bob確認電子郵件真的是Alice的,這樣代表那個憑證具有真實性,因此Bob可以信任Alice傳來的公鑰P~A~。 ```sequence note left of Alice: public key Pa Alice-CA: send email and Pa note right of CA: check note right of CA: email + Pa + Sc note right of CA: Certificate note right of CA: publicate Pc CA-Alice: send Certificate to Alice note left of Alice: Certificate Alice-Bob: send Certificate to Bob note right of Bob: Certificate CA-Bob: Bob get key Pc note right of Bob: decrypt Certificate using Pc note right of Bob: email + Pa Bob-Alice: send confirmation mail to Alice Alice-Bob: reply Bob's mail note right of Bob: I can trust this guy! ``` 利用這個機制,Bob不需要去相信第三方惡意傳送的假公鑰,因為那些公鑰並未擁有數位憑證。 #### **迷思澄清** Q1: 假設有第三人Eve取得了Alice的憑證,並用CA的公鑰解開憑證竊取Alice的email,那這個時候Eve不就可以拿著Alice的電郵申請假憑證,然後傳送給Bob了嗎? :::info 遇到這種情況,在憑證階段就能被發現。 首先,Eve根本就不能單靠Alice的email申請憑證,Eve如果沒有Alice的裝置,要申請憑證是不可能的。 就算Eve真的成功申請到假憑證,在Bob檢查信箱的階段就會被察覺。 Bob可以寄確認信給Alice,Alice本人可以親自回覆。多虧了現今電子郵件系統的防禦措施,如果Eve為了回覆確認信而嘗試登入Alice的信箱,系統會發一封簡訊到Alice的裝置確認是否讓外來裝置登入。 因此Eve不可能申請到假憑證,就算Eve擁有假憑證,但Bob終究能夠分辨而不會相信。 ::: Q2: 因為公鑰本身不具備來源確定性,必須透過憑證機構CA做擔保。那如果Eve偽裝成CA,製作假憑證,該怎麼辦?該怎麼確定CA的公鑰是可信的?這樣不就又回到最初的問題了嗎? :::info 事實上,這個憑證機構所製作的公鑰還有上層的機構給予憑證、做擔保。而上層的機構還有更上層的憑證機構做擔保...如此向上追溯,我們發現了最上層的機構 -- 稱為「**根憑證機構**」(Root CA, RCA),而這些機構不是政府機關就是大企業等深受社會信任的組織。而子機構的產生,也是先向這些大機構申請憑證,這些較大的組織便會替較小的組織的信用度做擔保,形成了層層下推的樹狀結構。 ::: #### **數位憑證的延伸應用** 網站進行通訊時也會用到數位憑證。不同於個人的憑證是和電子信箱綁在一起,網站背後的伺服器則是用**網域**(Domain Name, 透過DNS的解析可和該網頁的IP位址相互對應)申請憑證,確保管理此網站資訊的組織及伺服器相符。