# 與 Web 有關的密碼學入門筆記 _分享者:LiangC_ _分享日期:2021.08.13_ _分享團體:Appworks School 2019 冬季小組_ 主要依序介紹的項目為: - 談談密碼學 - 編碼、解碼 - 加密、解密 - 雜湊 --- ## 談談密碼學 ### 密碼學能做到什麼 1. 資訊的保密:確保資訊在傳遞後,只有特定授權者可以開啟。 2. 完整性驗證:確保資料沒有被串改。 3. 身份驗證:驗證資料傳送方的身份。 ### 密碼學做不到什麼 1. 學習完後,就可以當駭客嗎?不能,但密碼學會是其中的一環。 2. 能破解他人的密碼嗎?不能,但可以更知道密碼會如何儲存在資料庫、如何管理密碼比較安全。 3. 能繞過 wifi 或個人熱點密碼?不能,這反而與網路安全協定等等比較相關。 ### 密碼學是如何被實現? 滿滿的、超級多的應用數學!!!!!(今天不會提到,我也沒研究 XDDD) --- ## 編碼(Encode)與解碼(Decode) ### 編碼是什麼? 編碼是將原始資料經過一種演算方法,轉換成另一組資料的方式,而將編碼後的資料,轉換回原始資料的過程,則稱之為解碼。 特別注意的是,編碼並不是加密,僅是一種資料型態的轉換方式,只需要 try 到演算方式,就能還原資料,所以並不安全。 ### encodeURI / decodeURI [encodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) 可用來針對網址做 UTF-8 字元的編碼,不會對「 ASCII 英文字母、數字、 ~!@#$&*()=:/,;?+'」做處理,所以通常可以直接用於整個 url。 [decodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) 則是可以將編碼後的資料還原。 ```javascript= /** 應用 encodeURI & decodeURI 的時機 */ const url = 'https://www.google.com/search?q=密碼學+入門'; const encodeURL = encodeURI(url); const decodeURL = decodeURI(encodeURL); console.log('--- encodeURI 整個 url 依然是 url 格式 ---') console.log({ encodeURL, decodeURL }); const encodeURLComponent = encodeURIComponent(url); const decodeURLComponent = decodeURIComponent(encodeURLComponent); console.log('--- encodeURIComponent 整個 url 會有問題,url 格式有誤 ---') console.log({ encodeURLComponent, decodeURLComponent }); ``` ![](https://i.imgur.com/LY8LHSt.png) ### encodeURIComponent / decodeURIComponent [encodeURIComponent](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) 可用來針對網址做 UTF-8 字元的編碼,不會對「 ASCII 英文字母、數字、~!*()'」做處理,可以發現會對 / 之類的做處理,所以不可直接用於整個 url,通常會用於 query 的 value 值。 [decodeURIComponent](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent) 則是可以將編碼後的資料還原。 ```javascript= /** 應用 encodeURIComponent & decodeURIComponent 的時機 */ const param = 'https://www.programfarmer.com/'; const encodeURIComponentParam = encodeURIComponent(param); console.log('--- 將參數 encode 完整 ---') console.log({ encodeURIComponentParam, url: `https://www.google.com/search?q=${encodeURIComponentParam}` }); const encodeURIParam = encodeURI(param); console.log('--- 沒有將參數 encode 完整 ---') console.log({ encodeURIParam, url: `https://www.google.com/search?q=${encodeURIParam}` }); ``` ![](https://i.imgur.com/sbnGlWW.png) ### base64 編碼 [base64 編碼](https://zh.wikipedia.org/wiki/Base64)就是可以把任何資料,轉換成 [ASCII 字符](https://zh.wikipedia.org/wiki/ASCII)的一種方法。 終端機內建可以轉 base64 的語法如:`cat origin.txt | base64 > encode.txt`,意思是將 origin.txt 中的內容編碼成 base64 並且放入 encode.txt 中。。 base64 的轉換邏輯是: 1. 將資料拆分為 3 位元組(byte)的資料分群。 2. 將每個位元(byte)轉換成 ASCII 編碼。 3. 將 ASCII 編碼轉換成 0 與 1 ,放入 24 位元(bit)的緩衝區中。 4. 若資料不足 24 位元(bit),會用 0 補足。 5. 每次取出 6 位元(bit),轉換為十進位索引值。 6. 利用索引查找 base64 表獲取對應的值。 7. 重複上述步驟直到資料轉換完成。 例如:`Man` 編碼的結果為 `TWFu`。 ![](https://i.imgur.com/ZlocXlD.png) 1. Man 即為 3 位元組的資料。 2. 首先會針對每個文字,去查找對應的 ASCII 編碼,例如:M 的編碼數字會是 77。 ![](https://i.imgur.com/sNlPDKn.png) 3. 接著將 ASCII 編碼轉為 0 與 1 的位元,再分為 6 個一組(總共 24 位元)。 4. 接著 6 個一組的位元轉化回十進位索引。 5. 再用索引去查找 base64 表,獲取對應的值,即為結果。 ![](https://i.imgur.com/L819Uf3.png) base64 中的 64 其實是有含意的,因為最後轉換出來的索引表字元,就是 64 個。 - `a~z (26)` - `A~Z (26)` - `0~9 (10)` - `+ (1)` - `/ (1)` 但會發現經過 base64 編碼後,時常會有 `=` 的出現,那就是因為不滿 24 個位元補 0 的關係。可以注意到下表中,`000000` 的轉換即為 `=`。 ![](https://i.imgur.com/5VQhoFI.png) ### base64 應用: size 很小的圖片 可以將很小的圖片,例如:icon or logo 等,轉為 base64(例如:webpack 中 url-loader 可以做到),就無需從網路傳輸中讀取,像是下面這個 gif 圖的效果以及程式碼。 當然要特別注意的是,只有小圖片適合,通常會,因為大圖片轉換成 base64 後,會使 bundle 檔案 size 大增。 ![](https://i.imgur.com/oRGpqkU.gif) ```htmlmixed= <html> <body> <div> <h1>透過網址下載</h1> <img src="https://meet-trail-right.firebaseapp.com/src/assets/27894a7.png"> </div> <div> <h1>透過 Base64 呈現</h1> <img src="data:image/png;base64,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" /> </div> </body> </html> ``` 再次強調 base64 是一種編碼,而編碼只是一種資料格式的轉換,並非加密!像是轉網址轉為 QRcode 也可以說是一種編碼方式。 ### 霍夫曼編碼(Huffman Coding) 霍夫曼編碼的主要用途在於對資料進行「編碼壓縮」,主要流程概念是: 1. 依照要編碼壓縮的內容,其各個字元符號「出現的頻率」建立 Huffman Tree。 2. 依照該 Huffman Tree ,對資料內容進行編碼完成。 舉例而言,如果要對 `to be or not to be` 進行編碼,第一步會產生下面的 Huffman Tree: ![](https://i.imgur.com/DYUq7uB.png) 產生的概念是先計算各個字元出現的頻率: - 'r' 出現 1 次 - 'n' 出現 1 次 - 'b' 出現 2 次 - 'e' 出現 2 次 - 't' 出現 3 次 - 'o' 出現 4 次 - ' ' 出現 5 次 轉換成頻率數字的節點: ![](https://i.imgur.com/oQZpVpS.png) 接著由頻率最低的數字開始進行合併,每一輪都挑選數字最小的兩個節點合併,重複以上步驟,直到生成一棵樹為止,如下圖概念: ![](https://i.imgur.com/dl5eSGm.png) ![](https://i.imgur.com/XeyXsMd.png) ![](https://i.imgur.com/HmuArqV.png) ![](https://i.imgur.com/S4KAoLP.png) 最後在路徑上標註 0 or 1 集完成 Huffman Tree: ![](https://i.imgur.com/DYUq7uB.png) 接著第二步,根據這個 Huffman Tree 查找 `to be or not to be` 的編碼: - 't' => 111 - 'o' => 00 - ' ' => 10 - 'b' => 010 - 'e' => 011 - 'r' => 1100 - 'n' => 1101 所以結果為:11100100100111000110010110100111101110010010011。 這邊特別需要注意的是:「同樣的資料可能會生成不同的 Huffman Tree。在合併節點的過程中,不同的節點選擇,會產生不同的 Huffman Tree。另外,箭頭上的0、1標示方式也會造成影響。」 例如下面的結果就與上圖不同(可以忽略大小寫沒差): ![](https://i.imgur.com/0rtcIja.png) 但是只要是從同一套演算系統組合出的 Huffman Tree,最後出來的編碼結果會相同。另外如果字元越長、字元重複性越高(因為重複越高的字元,用了更少的位元紀錄結果),則壓縮的成果更顯著: 可以由這個玩看看:[Huffman Compressor Tool](http://craftyspace.net/huffman/) ![](https://i.imgur.com/PsJ1nYX.png) --- ## 加密(Encrypt)與解密(Decrypt) ### 加解密是什麼? 在編碼演算的過程中,需要帶一把 key 才能進行,即為加密。需要利用同一把 key 才能加密後的資料解碼,那就是解密。 它可以將明文轉換成他人難以理解的密文,同時,即便你知道編碼演算的方式,但如果沒有 key (推算不出 key) 就無法解密。 ### 凱薩加密法(Caesar cipher) - 加密方式:在 26 個字母中,把字母往右或左偏移 n 個位子(演算法),得出加密結果。並將 n 當作 key 來使用。 - 解密方式:透過 key 即可將加密結果解密。 - 舉例: - 演算往右邊移動,key 是 3:`hello world => khoor zruog`。 - 演算往右邊移動,key 是 5 : `hello world => mjqqt btwqi`。 - 線上工具:[Cryptii](https://cryptii.com/pipes/caesar-cipher)。 ![](https://i.imgur.com/AVBXkx0.png) 並不安全,因為「組合的數量太少」,key 是 1、27、53... 的結果會相同,如果以字母是正常排列來看,只有 26 種組合,很容易就破解,基本上沒在使用,但教學上都會是第一個例子,很容易理解XDD ![](https://i.imgur.com/bpnlIyD.png) *(如圖,把全部的組合都算出來,接著找到有意義的文字,就破解了)* ### AES(Advanced Encryption Standard)對稱加密 AES, Advanced Encryption Standard,其實是一套標準:[FIPS 197](https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf),而我們所說的 AES 演算法,其實是 Rijndael 演算法。 ![](https://i.imgur.com/vEwnHcT.png) *(裡面都是滿滿的數學)* 就到這裡為止!沒打算深入談 AES 怎麼實踐(也沒去研究其實XD)。只須先知道,有分成不同的金鑰長度的加密,分別為 128/192/256 位金鑰,其安全性基本上隨著金鑰越長越高。 - AES 128 : 2 的 128 次方種組合,約為 3.4*10^38。 - AES 192 : 2 的 192 次方種組合,約為 6.3*10^57。 - AES 256 : 2 的 256 次方種組合,約為 1.2*10^77。 在終端機可以直接實踐 AES 以及其他的加密解密方式,可以在終端機下指令 `openssl -` 看出所有支援的加解密演算。 ![](https://i.imgur.com/etK34qK.png) 創建一個檔案 `origin` 裡面有一段內容: ```htmlmixed= 這是一個不能被發現的秘密,嘿嘿嘿! ``` 接著利用 AES 128 加密,下指令:`openssl aes-128-cbc -in origin -out encrypt-aes`,會跳出輸入密碼的 input,輸入完畢後就加密成功。 ![](https://i.imgur.com/V3gj7vv.png) ```htmlmixed= Salted__�)��?���aK�0����-�B ``` 解密的時候加上`-d` 即可:`openssl aes-128-cbc -d -in encrypt-aes -out decrypt-aes`,接著要輸入密碼,假設輸入錯誤,就會有 `bad decrypt` 的錯誤訊息,並且無法解密。 ![](https://i.imgur.com/9qelj30.png) 成功的話,就可以在 `decrypt-aes` 看到: ```htmlmixed= 這是一個不能被發現的秘密,嘿嘿嘿! ``` ### AES 加密有可能被破解嗎? 任何的加密,都有可能被演算破解,只是需要的時間大小,以 AES 為例,直接截六角直撥課程的畫面說明。 ![](https://i.imgur.com/97zmuuh.png) 假定量子電腦被發明出來,大概也加速 10^8 ,因此以 AES 128 來看,也還是需要 10^10 年才能破解,所以不太需要擔心被強硬破解,不然就用更複雜的 192 or 256。 目前來看,AES 蠻普遍地被使用在業界中,其加密速度快且也不容易被破解。 ### 對稱加密的問題 對稱加密,如 AES,這類加密方法有個很大的問題,就是需要提供密碼給對方,除非每次都是當面將密碼交付給對方,不然將密碼在網路上傳輸都會有很大的風險存在,例如:傳輸時被第三方資料庫記錄,接著被盜用 ; 傳輸的過程中被中間人攻擊,拿走傳輸的資料。 ![](https://i.imgur.com/rngR2GE.png) *(共有的鑰匙可能在在 internet 傳輸過程被偷走)* 為了解決這個問題,就有了非對稱加密的方法。 ### 非對稱加密 所謂的非對稱加密,就是在加密的過程中,會產生兩組鑰匙密碼,一組是公鑰,一組私鑰,**公鑰加密的內容,只有私鑰能解開**。 假設有 A、B 兩人要加密檔案,就可以 A 在自己的電腦中產生公鑰與私鑰,接著將公鑰藉由網路傳輸給 B,請 B 用這把公鑰來加密檔案,接著把加密後的檔案回傳給 A,A 就可以用當初產生的私鑰來解密檔案。 在網路傳輸的過程中,如果加密後的檔案或是公鑰被偷走也沒關係,因為加密檔案只能由 A 本地端的私鑰才能解開。 ![](https://i.imgur.com/ZLEoxO5.png) ### RSA 非對稱加密 RSA 加密演算法是一種非對稱加密演算法,在公開金鑰加密和電子商業中被廣泛使用。RSA 是由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)在 1977 年一起提出的。當時他們三人都在麻省理工學院工作。RSA 就是他們三人姓氏開頭字母拼在一起組成的。 一樣可以透過 `openssl` 來使用,首先會需要產生一組公私鑰。 產生私鑰:`openssl genrsa -out private.pem`。 ![](https://i.imgur.com/ox5fwtB.png) ![](https://i.imgur.com/m18eD8H.png) 透過私鑰產生公鑰:`openssl rsa -pubout -in private.pem -out public.pem`。 ![](https://i.imgur.com/2SOjafL.png) ![](https://i.imgur.com/MLy8s0D.png) 有了公私鑰後,就可以來加密、解密檔案: - 利用公鑰加密檔案:`openssl rsautl -encrypt -in <in_file> -out <out_file> -pubin -inkey public.pem`。 ![](https://i.imgur.com/lHoVUxd.png) - 利用私鑰解密檔案:`openssl rsautl -decrypt -in <in_file> -out <out_file> -inkey private.pem`。 ![](https://i.imgur.com/LvAETD7.png) RSA 等非對稱加密的應用:[localhost https 憑證](https://letsencrypt.org/zh-tw/docs/certificates-for-localhost/) --- ## 雜湊(Hash) 雜湊並非加密!並沒有密碼。 將訊息資料進行雜湊演算(打亂、加料、混合)後,會輸出固定的雜湊值,會滿足幾個點: 1. 雜湊值是**無法反推出原來的訊息**。 2. 同樣的訊息和同樣的雜湊演算,一定會**得到相同的雜湊值**。 3. 在雜湊值夠長、演算複雜的情況下,可以讓**雜湊值趨近獨一無二**。 ### 身分證字號 ![](https://i.imgur.com/wbfnqNB.png) 如何計算出最後一位的檢查碼(雜湊演算)。 - 依照[字母數字對照表](https://www.cs.pu.edu.tw/~tsay/course/objprog/hw/hw4.html),將英文字母代號換為數字。 - 由左至右,第一位 x 1,第二位 x 9, 第三位 x 8......最後一位 x 1。 - 將所乘之積相加。 - 將上式所得之合除以 10 求得餘數。 - 以 10 減去上式所得餘數即為檢查碼。 透過檢查碼,是無法回推原本的值 `M14005165`。但檢查碼只會有 0 - 9,意思是這個雜湊函示演算出來的雜湊值,會非常容易發生碰撞 (Collision)。 ### MD5 MD5 訊息摘要演算法(MD5 Message-Digest Algorithm),一種被廣泛使用的密碼雜湊函式,可以產生出一個128位元(16位元組)的雜湊值(hash value),用於確保資訊傳輸完整一致。由美國密碼學家羅納德·李維斯特(Ronald Linn Rivest)設計,於 1992 年公開,用以取代 MD4 演算法。 可以發現 MD5 位元夠長、演算較為複雜,相比於身分證字號的檢查馬雜湊值,非常不容易被破解以及碰撞。 ![](https://i.imgur.com/CITbVtr.png) 由上圖可以發現,`password1` 與 `password3` 檔案中,基本上會是同樣的密碼(會說基本上是因為後來被發現會發生碰撞)。而每次 `md5 password1 password2 password3` 輸出的值一定相同。 然而,1996 年後被證實存在弱點,可以被破解,對於需要高度安全性的資料,建議改用其他演算法,如 SHA。2004 年,證實 MD5 演算法無法防止碰撞攻擊,因此不適用於安全性認證。 ### SHA SHA 安全雜湊演算法(Secure Hash Algorithm,縮寫為SHA)是一個密碼雜湊函式家族。能計算出一個數位訊息所對應到的,長度固定的字串(又稱訊息摘要)的演算法。且若輸入的訊息不同,它們對應到不同字串的機率很高。 其由美國國家安全局(NSA)所設計,並由美國國家標準與技術研究院(NIST)發布,是美國的政府標準,其分別是: - **SHA-0**:1993 年發布,當時稱做安全雜湊標準(Secure Hash Standard),發布之後很快就被 NSA 撤回,是 SHA-1 的前身。 - **SHA-1**:1995 年發布,SHA-1 在許多安全協定中廣為使用,包括 TLS、GnuPG、SSH、S/MIME 和 IPsec,是 MD5 的後繼者。但 SHA-1 的安全性在 2010 年以後,已經不被大多數的加密場景所接受。2017 年荷蘭密碼學研究小組 CWI 和 Google 正式宣布攻破了 SHA-1。 - **SHA-2**:2001 年發布,包括 `SHA-224`、`SHA-256`、`SHA-384`、`SHA-512`、`SHA-512/224`、`SHA-512/256`。SHA-2 目前沒有出現明顯的弱點。雖然至今尚未出現對 SHA-2 有效的攻擊,但它的演算法跟SHA-1 基本上仍然相似。 - **SHA-3**:2015 年正式發布,由於對 MD5 出現成功的破解,以及對 SHA-0 和 SHA-1 出現理論上破解的方法,NIST 感覺需要一個與之前演算法不同的,可替換的加密雜湊演算法,也就是現在的 SHA-3。 基本上可以把它當作 MD5 的替代版本,更長、碰撞機率更低、且演算法更不容易被破解。 ![](https://i.imgur.com/JJXCnGF.png) 數字越大代表越長的位元。 ### 雜湊的應用之一:驗證檔案資料的安全性 如何驗證第三方 lib 載入的檔案,沒有被駭客串改過?以 Bootstrap 為例。 Bootstrap 會在 link 提供 `integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We"` 就用來驗證 `https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css` 的腳本內容是否有被串改過。 因為 `https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css` 的內容經過 `SHA-384` 後,一定會是一樣的 `integrity` 值。 ![](https://i.imgur.com/HCaNIso.png) 如果把 `integrity` 改錯,就會爆出下面的錯誤,且 Btn 樣式會消失(瀏覽器就不會載入此份 css 檔案)。 ![](https://i.imgur.com/NWTGNlM.gif) ### 雜湊的應用之二:密碼登入的驗證機制 如果在資料庫中,儲存明文的密碼,那麼資料庫被偷走後,密碼就直接外洩。 密碼的用途是什麼?就是當作身份驗證比對的手段,那麼只要在資料庫中儲存能夠比對的雜湊值,那麼就能達成身份驗證的目標,同時資料庫被偷走,也不至於明文密碼外洩。 ![](https://i.imgur.com/I2a1dtK.png) 所以「忘記密碼」的流程才會是寄信請使用者直接重新設定密碼,而非給直接給使用者明文密碼,因為根本就沒有這筆資料計入在資料庫中。 因此,如果遇到有公司是忘記密碼後,把你的密碼寄給你,那就非常不安全。 不過駭客也有可能會把常用的密碼都先做成 hash 值,接著把資料庫偷走之後,用資料庫中的 hash 值比對,如果對出結果,那麼也就會知道明文密碼。=> 可以用加鹽(salt)手段預防。 所以要讓密碼安全: - 不要使用忘記密碼時,會寄明文密碼給你的網站。 - 不要使用太常見的密碼組合。 - 不要所有的網站都用同組密碼。 - 定期更新密碼。 --- ## 重點回顧 ### 編碼 encode - 只是將資料轉換成另外一種形式 - 不需要 key,只需要猜到轉換方式,就可解碼(不安全) - Base64、Huffman Coding、QRcode ### 加密 encrypt - 將資料明文轉換成難以識別的密文 - 利用 key 來保護資料的機密性 - 加密、解密都會需要 key - 對稱加密,加解密同一把 key : AES - 非對稱加密,加密公鑰,解密私鑰:RSA ### 雜湊 hash - 將資料打亂、加料、混合轉為雜湊值 - 雜湊值無法反推回原本的資料 - 相同資料的輸入,會產生相同的雜湊值輸出 - MD5、SHA ### 綜合應用 最後稍微提一下,在技術上其實會混用各種密碼學的手段,像是 JWT token 就是有 Hash 和 encode。 ![](https://i.imgur.com/8gOvdtB.png) ### JS 密碼套件 crypto-js https://www.npmjs.com/package/crypto-js --- ## 筆記中使用的參考資料或圖片來源 - [密碼學中的 Encode、Encrypt 跟 Hash 差異 | 六角學院](https://courses.hexschool.com/courses/2020/lectures/22896084) - [應用密碼學入門簡報 | @HITCON CMT 2018](https://hitcon.org/2018/CMT/slide-files/d1_s2_r4.pdf) - [escape,encodeURI,encodeURIComponent 有什么区别?](https://www.zhihu.com/question/21861899) - [【深入淺出】Base編碼 (Base64為例子)](https://dotblogs.com.tw/daniel/2019/05/09/001147) - [Huffman Coding 霍夫曼編碼](https://medium.com/@bhch3n/huffman-coding-%E9%9C%8D%E5%A4%AB%E6%9B%BC%E7%B7%A8%E7%A2%BC-3879df5ecddc) - [Huffman Tree Generator](https://www.csfieldguide.org.nz/en/interactives/huffman-tree/) - [對稱式加密演算法 - 大家都愛用的 AES](https://ithelp.ithome.com.tw/articles/10249488) - [基礎密碼學(對稱式與非對稱式加密技術)](https://medium.com/@RiverChan/%E5%9F%BA%E7%A4%8E%E5%AF%86%E7%A2%BC%E5%AD%B8-%E5%B0%8D%E7%A8%B1%E5%BC%8F%E8%88%87%E9%9D%9E%E5%B0%8D%E7%A8%B1%E5%BC%8F%E5%8A%A0%E5%AF%86%E6%8A%80%E8%A1%93-de25fd5fa537) - [網路安全(1) - 基礎密碼學](https://blog.techbridge.cc/2017/04/16/simple-cryptography/) - [MD5 | 維基百科](https://zh.wikipedia.org/wiki/MD5) - [SHA | 維基百科](https://zh.wikipedia.org/wiki/SHA%E5%AE%B6%E6%97%8F)