diff options
Diffstat (limited to 'Lib/hmac.py')
-rw-r--r-- | Lib/hmac.py | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/Lib/hmac.py b/Lib/hmac.py index 41d6c6cbd7..88c3fd5377 100644 --- a/Lib/hmac.py +++ b/Lib/hmac.py @@ -3,13 +3,11 @@ Implements the HMAC algorithm as described by RFC 2104. """ -def _strxor(s1, s2): - """Utility method. XOR the two strings s1 and s2 (must have same length). - """ - return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2)) +trans_5C = "".join ([chr (x ^ 0x5C) for x in xrange(256)]) +trans_36 = "".join ([chr (x ^ 0x36) for x in xrange(256)]) # The size of the digests returned by HMAC depends on the underlying -# hashing module used. +# hashing module used. Use digest_size from the instance of HMAC instead. digest_size = None # A unique object passed by HMAC.copy() to the HMAC constructor, in order @@ -22,6 +20,7 @@ class HMAC: This supports the API for Cryptographic Hash Functions (PEP 247). """ + blocksize = 64 # 512-bit HMAC; can be changed in subclasses. def __init__(self, key, msg = None, digestmod = None): """Create a new HMAC object. @@ -49,16 +48,13 @@ class HMAC: self.inner = self.digest_cons() self.digest_size = self.inner.digest_size - blocksize = 64 - ipad = "\x36" * blocksize - opad = "\x5C" * blocksize - + blocksize = self.blocksize if len(key) > blocksize: key = self.digest_cons(key).digest() key = key + chr(0) * (blocksize - len(key)) - self.outer.update(_strxor(key, opad)) - self.inner.update(_strxor(key, ipad)) + self.outer.update(key.translate(trans_5C)) + self.inner.update(key.translate(trans_36)) if msg is not None: self.update(msg) @@ -75,13 +71,22 @@ class HMAC: An update to this copy won't affect the original object. """ - other = HMAC(_secret_backdoor_key) + other = self.__class__(_secret_backdoor_key) other.digest_cons = self.digest_cons other.digest_size = self.digest_size other.inner = self.inner.copy() other.outer = self.outer.copy() return other + def _current(self): + """Return a hash object for the current state. + + To be used only internally with digest() and hexdigest(). + """ + h = self.outer.copy() + h.update(self.inner.digest()) + return h + def digest(self): """Return the hash value of this hashing object. @@ -89,15 +94,14 @@ class HMAC: not altered in any way by this function; you can continue updating the object after calling this function. """ - h = self.outer.copy() - h.update(self.inner.digest()) + h = self._current() return h.digest() def hexdigest(self): """Like digest(), but returns a string of hexadecimal digits instead. """ - return "".join([hex(ord(x))[2:].zfill(2) - for x in tuple(self.digest())]) + h = self._current() + return h.hexdigest() def new(key, msg = None, digestmod = None): """Create a new hashing object and return it. |