OLD | NEW |
| (Empty) |
1 """HMAC (Keyed-Hashing for Message Authentication) Python module. | |
2 | |
3 Implements the HMAC algorithm as described by RFC 2104. | |
4 | |
5 (This file is modified from the standard library version to do faster | |
6 copying) | |
7 """ | |
8 | |
9 def _strxor(s1, s2): | |
10 """Utility method. XOR the two strings s1 and s2 (must have same length). | |
11 """ | |
12 return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2)) | |
13 | |
14 # The size of the digests returned by HMAC depends on the underlying | |
15 # hashing module used. | |
16 digest_size = None | |
17 | |
18 class HMAC: | |
19 """RFC2104 HMAC class. | |
20 | |
21 This supports the API for Cryptographic Hash Functions (PEP 247). | |
22 """ | |
23 | |
24 def __init__(self, key, msg = None, digestmod = None): | |
25 """Create a new HMAC object. | |
26 | |
27 key: key for the keyed hash object. | |
28 msg: Initial input for the hash, if provided. | |
29 digestmod: A module supporting PEP 247. Defaults to the md5 module. | |
30 """ | |
31 if digestmod is None: | |
32 import md5 | |
33 digestmod = md5 | |
34 | |
35 if key == None: #TREVNEW - for faster copying | |
36 return #TREVNEW | |
37 | |
38 self.digestmod = digestmod | |
39 self.outer = digestmod.new() | |
40 self.inner = digestmod.new() | |
41 self.digest_size = digestmod.digest_size | |
42 | |
43 blocksize = 64 | |
44 ipad = "\x36" * blocksize | |
45 opad = "\x5C" * blocksize | |
46 | |
47 if len(key) > blocksize: | |
48 key = digestmod.new(key).digest() | |
49 | |
50 key = key + chr(0) * (blocksize - len(key)) | |
51 self.outer.update(_strxor(key, opad)) | |
52 self.inner.update(_strxor(key, ipad)) | |
53 if msg is not None: | |
54 self.update(msg) | |
55 | |
56 ## def clear(self): | |
57 ## raise NotImplementedError, "clear() method not available in HMAC." | |
58 | |
59 def update(self, msg): | |
60 """Update this hashing object with the string msg. | |
61 """ | |
62 self.inner.update(msg) | |
63 | |
64 def copy(self): | |
65 """Return a separate copy of this hashing object. | |
66 | |
67 An update to this copy won't affect the original object. | |
68 """ | |
69 other = HMAC(None) #TREVNEW - for faster copying | |
70 other.digest_size = self.digest_size #TREVNEW | |
71 other.digestmod = self.digestmod | |
72 other.inner = self.inner.copy() | |
73 other.outer = self.outer.copy() | |
74 return other | |
75 | |
76 def digest(self): | |
77 """Return the hash value of this hashing object. | |
78 | |
79 This returns a string containing 8-bit data. The object is | |
80 not altered in any way by this function; you can continue | |
81 updating the object after calling this function. | |
82 """ | |
83 h = self.outer.copy() | |
84 h.update(self.inner.digest()) | |
85 return h.digest() | |
86 | |
87 def hexdigest(self): | |
88 """Like digest(), but returns a string of hexadecimal digits instead. | |
89 """ | |
90 return "".join([hex(ord(x))[2:].zfill(2) | |
91 for x in tuple(self.digest())]) | |
92 | |
93 def new(key, msg = None, digestmod = None): | |
94 """Create a new hashing object and return it. | |
95 | |
96 key: The starting key for the hash. | |
97 msg: if available, will immediately be hashed into the object's starting | |
98 state. | |
99 | |
100 You can now feed arbitrary strings into the object using its update() | |
101 method, and can ask for the hash value at any time by calling its digest() | |
102 method. | |
103 """ | |
104 return HMAC(key, msg, digestmod) | |
OLD | NEW |