最近需要在程式中計算字串的 MD5,因而搜尋了不少資料,像是如何在終端機產生,或是在 C 程式碼中添加它。
什麼是 MD5
MD5 是一種加密用的雜湊函數(hash function),可由一份檔案或者一段字串產生出 128 位元的雜湊值(hash value)。即使輸入值的差異極小,得到的雜湊值也會有顯著差異,因而被用來確認資料傳輸後的完整性。
比如說,在下載映像檔後,計算該檔案的 MD5,就可以跟「映像檔提供者計算出的 MD5」做比較,若兩者一致,則可視作檔案正常、無毀損。
現在已被證實,MD5 無法防止碰撞攻擊,故不應使用於安全性憑證。
在終端機的運用
以 ubuntu 16.04 LTS 來說,預載就包含 md5sum
這個指令,只要加上檔名,即可在終端機得到 MD5。
1 | chihyu@chihyu-demo-ubuntu:~/project$ cat example_1.txt |
也可以直接加密字串,結尾有沒有換行符號會有顯著差異。
1 | chihyu@chihyu-demo-ubuntu:~/project$ echo 'chihyu' | md5sum |
如果不想要行末顯示的檔名或者 - ,可以搭配 cut
指令使用。
1 | chihyu@chihyu-demo-ubuntu:~/project$ echo -n 'chihyu' | md5sum | cut -d ' ' -f1 |
在 C 語言的運用
首先安裝必要的庫,才有函數可以呼叫,有些資料說要使用 sudo apt-get install openssl
,不過我使用的是這一個:
1 | sudo apt-get install libssl-dev |
接著,在 C 語言程式碼中引用 #include <openssl/md5.h>
就可以輕鬆產生 MD5。雖然我打算以 16 個 16 進位的字元來表示 MD5,但使用 openssl 函數返回的值會是 unsigned char array,尚須處理才會顯示成該格式。
以下是一段簡單的示範程式碼:
1 | chihyu@chihyu-demo-ubuntu:~/project$ cat md5.c |
需要特別注意的是,gcc 編譯時需要加上 -lcrypto
。
希望下次需要產生這個雜湊值時,這篇筆記可以讓自己迅速地解決。
額外技巧
使用 printf 搭配一些格式說明符(format specifier)可以改變顯示的格式,我個人較常使用的有:
%c
顯示字元(character)。%s
顯示字串(string)。%d
顯示 10 進位制(decimal)的整數。%x
與%X
顯示 16 進位制(hexadecimal)的整數。
16 進位制特別標注大小寫,是因為 10-15 會依據說明符,顯示為 a-f 或者 A-F。
也就是說,若將上方示範程式碼中 printf("%02x", digest[i]);
修改為 printf("%02X", digest[i]);
,結果也將變成 md5: '9E107D9D372BB6826BD81D3542A419D6'
。
至於 %
與 x
之間夾雜的 02
說明,無論該數值有幾位,都將以至少 2 個字元顯示,且以 0 填補空格。若未指定,則將顯示空白。另外,如果加上 -
將會靠左對齊。
1 | format: "%05X" |
還有一些比較進階,也比較少用的技巧,改天再整理出來。