0001 """HMAC (Keyed-Hashing for Message Authentication) Python module. 0002 0003 Implements the HMAC algorithm as described by RFC 2104. 0004 """ 0005 0006 def _strxor(s1, s2): 0007 """Utility method. XOR the two strings s1 and s2 (must have same length). 0008 """ 0009 return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2)) 0010 0011 # The size of the digests returned by HMAC depends on the underlying 0012 # hashing module used. 0013 digest_size = None 0014 0015 # A unique object passed by HMAC.copy() to the HMAC constructor, in order 0016 # that the latter return very quickly. HMAC("") in contrast is quite 0017 # expensive. 0018 _secret_backdoor_key = [] 0019 0020 class HMAC: 0021 """RFC2104 HMAC class. 0022 0023 This supports the API for Cryptographic Hash Functions (PEP 247). 0024 """ 0025 0026 def __init__(self, key, msg = None, digestmod = None): 0027 """Create a new HMAC object. 0028 0029 key: key for the keyed hash object. 0030 msg: Initial input for the hash, if provided. 0031 digestmod: A module supporting PEP 247. Defaults to the md5 module. 0032 """ 0033 0034 if key is _secret_backdoor_key: # cheap 0035 return 0036 0037 if digestmod is None: 0038 import md5 0039 digestmod = md5 0040 0041 self.digestmod = digestmod 0042 self.outer = digestmod.new() 0043 self.inner = digestmod.new() 0044 self.digest_size = digestmod.digest_size 0045 0046 blocksize = 64 0047 ipad = "\x36" * blocksize 0048 opad = "\x5C" * blocksize 0049 0050 if len(key) > blocksize: 0051 key = digestmod.new(key).digest() 0052 0053 key = key + chr(0) * (blocksize - len(key)) 0054 self.outer.update(_strxor(key, opad)) 0055 self.inner.update(_strxor(key, ipad)) 0056 if msg is not None: 0057 self.update(msg) 0058 0059 ## def clear(self): 0060 ## raise NotImplementedError, "clear() method not available in HMAC." 0061 0062 def update(self, msg): 0063 """Update this hashing object with the string msg. 0064 """ 0065 self.inner.update(msg) 0066 0067 def copy(self): 0068 """Return a separate copy of this hashing object. 0069 0070 An update to this copy won't affect the original object. 0071 """ 0072 other = HMAC(_secret_backdoor_key) 0073 other.digestmod = self.digestmod 0074 other.digest_size = self.digest_size 0075 other.inner = self.inner.copy() 0076 other.outer = self.outer.copy() 0077 return other 0078 0079 def digest(self): 0080 """Return the hash value of this hashing object. 0081 0082 This returns a string containing 8-bit data. The object is 0083 not altered in any way by this function; you can continue 0084 updating the object after calling this function. 0085 """ 0086 h = self.outer.copy() 0087 h.update(self.inner.digest()) 0088 return h.digest() 0089 0090 def hexdigest(self): 0091 """Like digest(), but returns a string of hexadecimal digits instead. 0092 """ 0093 return "".join([hex(ord(x))[2:].zfill(2) 0094 for x in tuple(self.digest())]) 0095 0096 def new(key, msg = None, digestmod = None): 0097 """Create a new hashing object and return it. 0098 0099 key: The starting key for the hash. 0100 msg: if available, will immediately be hashed into the object's starting 0101 state. 0102 0103 You can now feed arbitrary strings into the object using its update() 0104 method, and can ask for the hash value at any time by calling its digest() 0105 method. 0106 """ 0107 return HMAC(key, msg, digestmod) 0108
Generated by PyXR 0.9.4