==md5 模塊== ``md5`` (Message-Digest Algorithm 5)模塊用於計算信息密文(信息摘要). ``md5`` 算法計算一個強壯的128位密文. 這意味着若是兩個字符串是不一樣的, 那麼有極高可能它們的 ``md5`` 也不一樣. 也就是說, 給定一個 ``md5`` 密文, 那麼幾乎沒有可能再找到另個字符串的密文與此相同. [Example 2-35 #eg-2-35] 展現瞭如何使用 ``md5`` 模塊. ====Example 2-35. 使用 md5 模塊====[eg-2-35] ``` File: md5-example-1.py import md5 hash = md5.new() hash.update("spam, spam, and eggs") print repr(hash.digest()) *B* 'L\005J\243\266\355\243u`\305r\203\267\020F\303'*b* ``` 注意這裏的校驗和是一個二進制字符串. [Example 2-36 #eg-2-36] 展現瞭如何得到一個十六進制或 base64 編碼的字符串. ====Example 2-36. 使用 md5 模塊得到十六進制或 base64 編碼的 md5 值====[eg-2-36] ``` File: md5-example-2.py import md5 import string import base64 hash = md5.new() hash.update("spam, spam, and eggs") value = hash.digest() print hash.hexdigest() # before 2.0, the above can be written as # 在 2.0 前, 以上應該寫作: # print string.join(map(lambda v: "%02x" % ord(v), value), "") print base64.encodestring(value) *B*4c054aa3b6eda37560c57283b71046c3 TAVKo7bto3VgxXKDtxBGww==*b* ``` [Example 2-37 #eg-2-37] 展現瞭如何使用 ``md5`` 校驗和來處理口令的發送與應答的驗證(不過咱們將稍候討論這裏使用隨機數字所帶來的問題). ====Example 2-37. 使用 md5 模塊來處理口令的發送與應答的驗證====[eg-2-37] ``` File: md5-example-3.py import md5 import string, random def getchallenge(): # generate a 16-byte long random string. (note that the built- # in pseudo-random generator uses a 24-bit seed, so this is not # as good as it may seem...) # 生成一個 16 字節長的隨機字符串. 注意內建的僞隨機生成器 # 使用的是 24 位的種子(seed), 因此這裏這樣用並很差.. challenge = map(lambda i: chr(random.randint(0, 255)), range(16)) return string.join(challenge, "") def getresponse(password, challenge): # calculate combined digest for password and challenge # 計算密碼和質詢(challenge)的聯合密文 m = md5.new() m.update(password) m.update(challenge) return m.digest() # # server/client communication # 服務器/客戶端通信 # 1. client connects. server issues challenge. # 1. 客戶端鏈接, 服務器發佈質詢(challenge) print "client:", "connect" challenge = getchallenge() print "server:", repr(challenge) # 2. client combines password and challenge, and calculates # the response. # 2. 客戶端計算密碼和質詢(challenge)的組合後的密文 client_response = getresponse("trustno1", challenge) print "client:", repr(client_response) # 3. server does the same, and compares the result with the # client response. the result is a safe login in which the # password is never sent across the communication channel. # 3. 服務器作一樣的事, 而後比較結果與客戶端的返回, # 判斷是否容許用戶登錄. 這樣作密碼沒有在通信中明文傳輸. server_response = getresponse("trustno1", challenge) if server_response == client_response: print "server:", "login ok" *B*client: connect server: '\334\352\227Z#\272\273\212KG\330\265\032>\311o' client: "l'\305\240-x\245\237\035\225A\254\233\337\225\001" server: login ok*b* ``` [Example 2-38 #eg-2-38] 提供了 ``md5`` 的一個變種, 你能夠經過標記信息來判斷它是否在網絡傳輸過程當中被修改(丟失). ====Example 2-38. 使用 md5 模塊檢查數據完整性====[eg-2-38] ``` File: md5-example-4.py import md5 import array class HMAC_MD5: # keyed md5 message authentication def _ _init_ _(self, key): if len(key) > 64: key = md5.new(key).digest() ipad = array.array("B", [0x36] * 64) opad = array.array("B", [0x5C] * 64) for i in range(len(key)): ipad[i] = ipad[i] ^ ord(key[i]) opad[i] = opad[i] ^ ord(key[i]) self.ipad = md5.md5(ipad.tostring()) self.opad = md5.md5(opad.tostring()) def digest(self, data): ipad = self.ipad.copy() opad = self.opad.copy() ipad.update(data) opad.update(ipad.digest()) return opad.digest() # # simulate server end # 模擬服務器端 key = "this should be a well-kept secret" message = open("samples/sample.txt").read() signature = HMAC_MD5(key).digest(message) # (send message and signature across a public network) # (通過由網絡發送信息和簽名) # # simulate client end #模擬客戶端 key = "this should be a well-kept secret" client_signature = HMAC_MD5(key).digest(message) if client_signature == signature: print "this is the original message:" print print message else: print "someone has modified the message!!!" ``` ``copy`` 方法會對這個內部對象狀態作一個快照( snapshot ). 這容許你預先計算部分密文摘要(例如 [Example 2-38 #eg-2-38] 中的 padded key). 該算法的細節請參閱 //HMAC-MD5:Keyed-MD5 for Message Authentication// ( http://www.research.ibm.com/security/draft-ietf-ipsec-hmac-md5-00.txt ) by Krawczyk, 或其餘. *Note*千萬別忘記內建的僞隨機生成器對於加密操做而言並不合適. 千萬當心. *note*