假設每台機器都有編號,而且是以流水號的方式編排 0001, 0002, 0003 ...
要為每台機器預留一個 publish URL 像是 http://anything.com/0001/data,但又不想輕易讓其他人知道規則,例如 user 0001 可以用 http://anything.com/0002/data 拿到別人的 data。
方法一:Hash
第一想到的是把 id 經 MD5 hash,但 hash 就是有機會 collision,雖然這個機率比被雷打到還低很多,但機率這種東西就是有可能發生嘛!於是我就把所有的編號都拿去做 MD5,最後證明了沒有 collision 的問題。MD5("0001") = 25bbdcd06c32d477f7fa1c3e4a91b032 http://anything.com/25bbdcd06c32d477f7fa1c3e4a91b032/data是不是找不出其規則了
但又產生了另一個問題,短字串的 hash 結果很容易被彩虹表 (Rainbow table) 破解,意指先把所有 hash 結果計算出來,利用查表的方式反推原始字串,所以會有加 salt 的概念,也就是把原始字串先"處理"一下再去 hash,可能是額外加一些字串,或是反轉之類的,長度增加了可以降低被反推的機會,即使被反推回來也很難獲得原始字串。
SALT("0001") = 0a0b0c1d MD5("0a0b0c1d") = b906c4ea093173e4c673ab6540696f0c http://anything.com/b906c4ea093173e4c673ab6540696f0c/data這樣子有比較複雜了吧!
salt 的方式有很多種,例如 MD5 兩次,或用其他 hash function,但要記得不能有兩個字串經過 salt 的結果是一樣的。
方法二:Encrypt
由於原始字串經過很大的變化,所以我也沒辦法驗證 collision 發生的可能性,後來決定還是改用加密法,加密法是 1 對 1 函數,沒有 collision 的問題。
DES(key: "god", plaintext: "0001") = d4f96d5da8bd0e6e http://anything.com/d4f96d5da8bd0e6e/data過程中比較棘手的是加密法的 變數實在太多,以 DES 來說,我用 openssl crypto library 時,要輸入 mode (cbc, ebc, cfb...)、input 又有分 64bit/128bit、是否加 padding,當想用 其他方式(pyDes、Online encrypt tool)來驗證時,竟然湊不出一樣的 ><
後記:
其實我需要的應該是一種只有自己知道的 encode/decode 方式,而且必須要是 id 加減1時,編碼結果就會變動很大,避免有心人士反推。用 encryption 是有點大材小用,但至少是 well known 的,所以各種語言都很容易找到 library,不需要自己 implement。順便復習一下
- Encode/Decode
資料傳遞時的一種表達方式
base64 encode, url encode ...
- Encrypt/Decrypt
以密文的方式傳遞資料,只有知道 key 的人可以解開得到明文,又分成對稱加密與非對稱加密
AES, DES, Blowfish ...
- Hash
驗證資料完整性
MD5, SHA1, CRC32
Once the steel fabrication course of stops, the part strikes to extra companies to achieve the detailed specs for the completed product. We perform many fabrication companies in-house, whereas others are via sweater dress our select trusted companions. Nonetheless, we guarantee you’ll get the components completed to your satisfaction and end-product specs. The steel fabrication trade willcontinue altering and growingas know-how and elevated market demand promise extra streamlined fabrication processes.
回覆刪除