PyXR

c:\python24\lib \ hmac.py



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
SourceForge.net Logo