15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""HMAC (Keyed-Hashing for Message Authentication) Python module. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Implements the HMAC algorithm as described by RFC 2104. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(This file is modified from the standard library version to do faster 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)copying) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _strxor(s1, s2): 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Utility method. XOR the two strings s1 and s2 (must have same length). 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2)) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The size of the digests returned by HMAC depends on the underlying 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# hashing module used. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)digest_size = None 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HMAC: 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """RFC2104 HMAC class. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This supports the API for Cryptographic Hash Functions (PEP 247). 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, key, msg = None, digestmod = None): 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Create a new HMAC object. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key: key for the keyed hash object. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg: Initial input for the hash, if provided. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) digestmod: A module supporting PEP 247. Defaults to the md5 module. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if digestmod is None: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import md5 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) digestmod = md5 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if key == None: #TREVNEW - for faster copying 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return #TREVNEW 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.digestmod = digestmod 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.outer = digestmod.new() 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.inner = digestmod.new() 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.digest_size = digestmod.digest_size 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocksize = 64 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipad = "\x36" * blocksize 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opad = "\x5C" * blocksize 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(key) > blocksize: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = digestmod.new(key).digest() 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = key + chr(0) * (blocksize - len(key)) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.outer.update(_strxor(key, opad)) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.inner.update(_strxor(key, ipad)) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if msg is not None: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.update(msg) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)## def clear(self): 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)## raise NotImplementedError, "clear() method not available in HMAC." 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def update(self, msg): 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Update this hashing object with the string msg. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.inner.update(msg) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def copy(self): 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return a separate copy of this hashing object. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) An update to this copy won't affect the original object. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other = HMAC(None) #TREVNEW - for faster copying 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.digest_size = self.digest_size #TREVNEW 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.digestmod = self.digestmod 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.inner = self.inner.copy() 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.outer = self.outer.copy() 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return other 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def digest(self): 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Return the hash value of this hashing object. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This returns a string containing 8-bit data. The object is 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) not altered in any way by this function; you can continue 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updating the object after calling this function. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = self.outer.copy() 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h.update(self.inner.digest()) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return h.digest() 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def hexdigest(self): 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Like digest(), but returns a string of hexadecimal digits instead. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "".join([hex(ord(x))[2:].zfill(2) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for x in tuple(self.digest())]) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def new(key, msg = None, digestmod = None): 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Create a new hashing object and return it. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key: The starting key for the hash. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg: if available, will immediately be hashed into the object's starting 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) You can now feed arbitrary strings into the object using its update() 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method, and can ask for the hash value at any time by calling its digest() 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HMAC(key, msg, digestmod) 105