lmgsanm

每天学习一点,每天进步一点点…… Tomorrow is another beatifull day

导航

python模块:hmac

  1 """HMAC (Keyed-Hashing for Message Authentication) Python module.
  2 
  3 Implements the HMAC algorithm as described by RFC 2104.
  4 """
  5 
  6 import warnings as _warnings
  7 from _operator import _compare_digest as compare_digest
  8 import hashlib as _hashlib
  9 
 10 trans_5C = bytes((x ^ 0x5C) for x in range(256))
 11 trans_36 = bytes((x ^ 0x36) for x in range(256))
 12 
 13 # The size of the digests returned by HMAC depends on the underlying
 14 # hashing module used.  Use digest_size from the instance of HMAC instead.
 15 digest_size = None
 16 
 17 
 18 
 19 class HMAC:
 20     """RFC 2104 HMAC class.  Also complies with RFC 4231.
 21 
 22     This supports the API for Cryptographic Hash Functions (PEP 247).
 23     """
 24     blocksize = 64  # 512-bit HMAC; can be changed in subclasses.
 25 
 26     def __init__(self, key, msg = None, digestmod = None):
 27         """Create a new HMAC object.
 28 
 29         key:       key for the keyed hash object.
 30         msg:       Initial input for the hash, if provided.
 31         digestmod: A module supporting PEP 247.  *OR*
 32                    A hashlib constructor returning a new hash object. *OR*
 33                    A hash name suitable for hashlib.new().
 34                    Defaults to hashlib.md5.
 35                    Implicit default to hashlib.md5 is deprecated and will be
 36                    removed in Python 3.6.
 37 
 38         Note: key and msg must be a bytes or bytearray objects.
 39         """
 40 
 41         if not isinstance(key, (bytes, bytearray)):
 42             raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
 43 
 44         if digestmod is None:
 45             _warnings.warn("HMAC() without an explicit digestmod argument "
 46                            "is deprecated.", PendingDeprecationWarning, 2)
 47             digestmod = _hashlib.md5
 48 
 49         if callable(digestmod):
 50             self.digest_cons = digestmod
 51         elif isinstance(digestmod, str):
 52             self.digest_cons = lambda d=b'': _hashlib.new(digestmod, d)
 53         else:
 54             self.digest_cons = lambda d=b'': digestmod.new(d)
 55 
 56         self.outer = self.digest_cons()
 57         self.inner = self.digest_cons()
 58         self.digest_size = self.inner.digest_size
 59 
 60         if hasattr(self.inner, 'block_size'):
 61             blocksize = self.inner.block_size
 62             if blocksize < 16:
 63                 _warnings.warn('block_size of %d seems too small; using our '
 64                                'default of %d.' % (blocksize, self.blocksize),
 65                                RuntimeWarning, 2)
 66                 blocksize = self.blocksize
 67         else:
 68             _warnings.warn('No block_size attribute on given digest object; '
 69                            'Assuming %d.' % (self.blocksize),
 70                            RuntimeWarning, 2)
 71             blocksize = self.blocksize
 72 
 73         # self.blocksize is the default blocksize. self.block_size is
 74         # effective block size as well as the public API attribute.
 75         self.block_size = blocksize
 76 
 77         if len(key) > blocksize:
 78             key = self.digest_cons(key).digest()
 79 
 80         key = key.ljust(blocksize, b'\0')
 81         self.outer.update(key.translate(trans_5C))
 82         self.inner.update(key.translate(trans_36))
 83         if msg is not None:
 84             self.update(msg)
 85 
 86     @property
 87     def name(self):
 88         return "hmac-" + self.inner.name
 89 
 90     def update(self, msg):
 91         """Update this hashing object with the string msg.
 92         """
 93         self.inner.update(msg)
 94 
 95     def copy(self):
 96         """Return a separate copy of this hashing object.
 97 
 98         An update to this copy won't affect the original object.
 99         """
100         # Call __new__ directly to avoid the expensive __init__.
101         other = self.__class__.__new__(self.__class__)
102         other.digest_cons = self.digest_cons
103         other.digest_size = self.digest_size
104         other.inner = self.inner.copy()
105         other.outer = self.outer.copy()
106         return other
107 
108     def _current(self):
109         """Return a hash object for the current state.
110 
111         To be used only internally with digest() and hexdigest().
112         """
113         h = self.outer.copy()
114         h.update(self.inner.digest())
115         return h
116 
117     def digest(self):
118         """Return the hash value of this hashing object.
119 
120         This returns a string containing 8-bit data.  The object is
121         not altered in any way by this function; you can continue
122         updating the object after calling this function.
123         """
124         h = self._current()
125         return h.digest()
126 
127     def hexdigest(self):
128         """Like digest(), but returns a string of hexadecimal digits instead.
129         """
130         h = self._current()
131         return h.hexdigest()
132 
133 def new(key, msg = None, digestmod = None):
134     """Create a new hashing object and return it.
135 
136     key: The starting key for the hash.
137     msg: if available, will immediately be hashed into the object's starting
138     state.
139 
140     You can now feed arbitrary strings into the object using its update()
141     method, and can ask for the hash value at any time by calling its digest()
142     method.
143     """
144     return HMAC(key, msg, digestmod)
hmac

 

posted on 2018-01-30 19:55  lmgsanm  阅读(748)  评论(0编辑  收藏  举报