mirror of https://github.com/python/cpython.git
Issue #18775: Add name and block_size attribute to HMAC object. They now
provide the same API elements as non-keyed cryptographic hash functions.
This commit is contained in:
parent
634919a9fa
commit
c4ab11050d
|
@ -79,6 +79,25 @@ An HMAC object has the following methods:
|
||||||
compute the digests of strings that share a common initial substring.
|
compute the digests of strings that share a common initial substring.
|
||||||
|
|
||||||
|
|
||||||
|
A hash object has the following attributes:
|
||||||
|
|
||||||
|
.. attribute:: HMAC.digest_size
|
||||||
|
|
||||||
|
The size of the resulting HMAC digest in bytes.
|
||||||
|
|
||||||
|
.. attribute:: HMAC.block_size
|
||||||
|
|
||||||
|
The internal block size of the hash algorithm in bytes.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
.. attribute:: HMAC.name
|
||||||
|
|
||||||
|
The canonical name of this HMAC, always lowercase, e.g. ``hmac-md5``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
This module also provides the following helper function:
|
This module also provides the following helper function:
|
||||||
|
|
||||||
.. function:: compare_digest(a, b)
|
.. function:: compare_digest(a, b)
|
||||||
|
|
|
@ -70,6 +70,10 @@ def __init__(self, key, msg = None, digestmod = None):
|
||||||
RuntimeWarning, 2)
|
RuntimeWarning, 2)
|
||||||
blocksize = self.blocksize
|
blocksize = self.blocksize
|
||||||
|
|
||||||
|
# self.blocksize is the default blocksize. self.block_size is
|
||||||
|
# effective block size as well as the public API attribute.
|
||||||
|
self.block_size = blocksize
|
||||||
|
|
||||||
if len(key) > blocksize:
|
if len(key) > blocksize:
|
||||||
key = self.digest_cons(key).digest()
|
key = self.digest_cons(key).digest()
|
||||||
|
|
||||||
|
@ -79,6 +83,10 @@ def __init__(self, key, msg = None, digestmod = None):
|
||||||
if msg is not None:
|
if msg is not None:
|
||||||
self.update(msg)
|
self.update(msg)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return "hmac-" + self.inner.name
|
||||||
|
|
||||||
def update(self, msg):
|
def update(self, msg):
|
||||||
"""Update this hashing object with the string msg.
|
"""Update this hashing object with the string msg.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -12,8 +12,16 @@ def test_md5_vectors(self):
|
||||||
def md5test(key, data, digest):
|
def md5test(key, data, digest):
|
||||||
h = hmac.HMAC(key, data, digestmod=hashlib.md5)
|
h = hmac.HMAC(key, data, digestmod=hashlib.md5)
|
||||||
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
||||||
|
self.assertEqual(h.name, "hmac-md5")
|
||||||
|
self.assertEqual(h.digest_size, 16)
|
||||||
|
self.assertEqual(h.block_size, 64)
|
||||||
|
|
||||||
h = hmac.HMAC(key, data, digestmod='md5')
|
h = hmac.HMAC(key, data, digestmod='md5')
|
||||||
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
||||||
|
self.assertEqual(h.name, "hmac-md5")
|
||||||
|
self.assertEqual(h.digest_size, 16)
|
||||||
|
self.assertEqual(h.block_size, 64)
|
||||||
|
|
||||||
|
|
||||||
md5test(b"\x0b" * 16,
|
md5test(b"\x0b" * 16,
|
||||||
b"Hi There",
|
b"Hi There",
|
||||||
|
@ -48,8 +56,15 @@ def test_sha_vectors(self):
|
||||||
def shatest(key, data, digest):
|
def shatest(key, data, digest):
|
||||||
h = hmac.HMAC(key, data, digestmod=hashlib.sha1)
|
h = hmac.HMAC(key, data, digestmod=hashlib.sha1)
|
||||||
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
||||||
|
self.assertEqual(h.name, "hmac-sha1")
|
||||||
|
self.assertEqual(h.digest_size, 20)
|
||||||
|
self.assertEqual(h.block_size, 64)
|
||||||
|
|
||||||
h = hmac.HMAC(key, data, digestmod='sha1')
|
h = hmac.HMAC(key, data, digestmod='sha1')
|
||||||
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
self.assertEqual(h.hexdigest().upper(), digest.upper())
|
||||||
|
self.assertEqual(h.name, "hmac-sha1")
|
||||||
|
self.assertEqual(h.digest_size, 20)
|
||||||
|
self.assertEqual(h.block_size, 64)
|
||||||
|
|
||||||
|
|
||||||
shatest(b"\x0b" * 20,
|
shatest(b"\x0b" * 20,
|
||||||
|
@ -81,12 +96,20 @@ def shatest(key, data, digest):
|
||||||
b"and Larger Than One Block-Size Data"),
|
b"and Larger Than One Block-Size Data"),
|
||||||
"e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
|
"e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
|
||||||
|
|
||||||
def _rfc4231_test_cases(self, hashfunc, hashname):
|
def _rfc4231_test_cases(self, hashfunc, hash_name, digest_size, block_size):
|
||||||
def hmactest(key, data, hexdigests):
|
def hmactest(key, data, hexdigests):
|
||||||
|
hmac_name = "hmac-" + hash_name
|
||||||
h = hmac.HMAC(key, data, digestmod=hashfunc)
|
h = hmac.HMAC(key, data, digestmod=hashfunc)
|
||||||
self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
|
self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
|
||||||
h = hmac.HMAC(key, data, digestmod=hashname)
|
self.assertEqual(h.name, hmac_name)
|
||||||
|
self.assertEqual(h.digest_size, digest_size)
|
||||||
|
self.assertEqual(h.block_size, block_size)
|
||||||
|
|
||||||
|
h = hmac.HMAC(key, data, digestmod=hash_name)
|
||||||
self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
|
self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
|
||||||
|
self.assertEqual(h.name, hmac_name)
|
||||||
|
self.assertEqual(h.digest_size, digest_size)
|
||||||
|
self.assertEqual(h.block_size, block_size)
|
||||||
|
|
||||||
|
|
||||||
# 4.2. Test Case 1
|
# 4.2. Test Case 1
|
||||||
|
@ -197,16 +220,16 @@ def hmactest(key, data, hexdigests):
|
||||||
})
|
})
|
||||||
|
|
||||||
def test_sha224_rfc4231(self):
|
def test_sha224_rfc4231(self):
|
||||||
self._rfc4231_test_cases(hashlib.sha224, 'sha224')
|
self._rfc4231_test_cases(hashlib.sha224, 'sha224', 28, 64)
|
||||||
|
|
||||||
def test_sha256_rfc4231(self):
|
def test_sha256_rfc4231(self):
|
||||||
self._rfc4231_test_cases(hashlib.sha256, 'sha256')
|
self._rfc4231_test_cases(hashlib.sha256, 'sha256', 32, 64)
|
||||||
|
|
||||||
def test_sha384_rfc4231(self):
|
def test_sha384_rfc4231(self):
|
||||||
self._rfc4231_test_cases(hashlib.sha384, 'sha384')
|
self._rfc4231_test_cases(hashlib.sha384, 'sha384', 48, 128)
|
||||||
|
|
||||||
def test_sha512_rfc4231(self):
|
def test_sha512_rfc4231(self):
|
||||||
self._rfc4231_test_cases(hashlib.sha512, 'sha512')
|
self._rfc4231_test_cases(hashlib.sha512, 'sha512', 64, 128)
|
||||||
|
|
||||||
def test_legacy_block_size_warnings(self):
|
def test_legacy_block_size_warnings(self):
|
||||||
class MockCrazyHash(object):
|
class MockCrazyHash(object):
|
||||||
|
|
|
@ -59,6 +59,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #18775: Add name and block_size attribute to HMAC object. They now
|
||||||
|
provide the same API elements as non-keyed cryptographic hash functions.
|
||||||
|
|
||||||
- Issue #17276: MD5 as default digestmod for HMAC is deprecated. The HMAC
|
- Issue #17276: MD5 as default digestmod for HMAC is deprecated. The HMAC
|
||||||
module supports digestmod names, e.g. hmac.HMAC('sha1').
|
module supports digestmod names, e.g. hmac.HMAC('sha1').
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue