Kaydet (Commit) a19f80c6 authored tarafından Guido van Rossum's avatar Guido van Rossum

Merged revisions 58862-58885 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r58868 | gregory.p.smith | 2007-11-05 16:19:03 -0800 (Mon, 05 Nov 2007) | 3 lines

  Fixes Issue 1385: The hmac module now computes the correct hmac when using
  hashes with a block size other than 64 bytes (such as sha384 and sha512).
........
üst a3538ebf
...@@ -52,6 +52,10 @@ spammish repetition'``:: ...@@ -52,6 +52,10 @@ spammish repetition'``::
>>> m.update(b" the spammish repetition") >>> m.update(b" the spammish repetition")
>>> m.digest() >>> m.digest()
b'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9' b'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
>>> m.digest_size
16
>>> m.block_size
64
More condensed:: More condensed::
...@@ -76,7 +80,11 @@ returned by the constructors: ...@@ -76,7 +80,11 @@ returned by the constructors:
.. data:: digest_size .. data:: digest_size
The size of the resulting digest in bytes. The size of the resulting hash in bytes.
.. data:: block_size
The internal block size of the hash algorithm in bytes.
A hash object has the following methods: A hash object has the following methods:
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
Implements the HMAC algorithm as described by RFC 2104. Implements the HMAC algorithm as described by RFC 2104.
""" """
import warnings as _warnings
trans_5C = bytes((x ^ 0x5C) for x in range(256)) trans_5C = bytes((x ^ 0x5C) for x in range(256))
trans_36 = bytes((x ^ 0x36) for x in range(256)) trans_36 = bytes((x ^ 0x36) for x in range(256))
...@@ -16,7 +18,7 @@ digest_size = None ...@@ -16,7 +18,7 @@ digest_size = None
_secret_backdoor_key = [] _secret_backdoor_key = []
class HMAC: class HMAC:
"""RFC2104 HMAC class. """RFC 2104 HMAC class. Also complies with RFC 4231.
This supports the API for Cryptographic Hash Functions (PEP 247). This supports the API for Cryptographic Hash Functions (PEP 247).
""" """
...@@ -52,7 +54,21 @@ class HMAC: ...@@ -52,7 +54,21 @@ class HMAC:
self.inner = self.digest_cons() self.inner = self.digest_cons()
self.digest_size = self.inner.digest_size self.digest_size = self.inner.digest_size
blocksize = self.blocksize if hasattr(self.inner, 'block_size'):
blocksize = self.inner.block_size
if blocksize < 16:
# Very low blocksize, most likely a legacy value like
# Lib/sha.py and Lib/md5.py have.
_warnings.warn('block_size of %d seems too small; using our '
'default of %d.' % (blocksize, self.blocksize),
RuntimeWarning, 2)
blocksize = self.blocksize
else:
_warnings.warn('No block_size attribute on given digest object; '
'Assuming %d.' % (self.blocksize),
RuntimeWarning, 2)
blocksize = self.blocksize
if len(key) > blocksize: if len(key) > blocksize:
key = self.digest_cons(key).digest() key = self.digest_cons(key).digest()
......
import hmac import hmac
from hashlib import sha1 import hashlib
import unittest import unittest
import warnings
from test import test_support from test import test_support
class TestVectorsTestCase(unittest.TestCase): class TestVectorsTestCase(unittest.TestCase):
...@@ -43,7 +44,7 @@ class TestVectorsTestCase(unittest.TestCase): ...@@ -43,7 +44,7 @@ class TestVectorsTestCase(unittest.TestCase):
def test_sha_vectors(self): def test_sha_vectors(self):
def shatest(key, data, digest): def shatest(key, data, digest):
h = hmac.HMAC(key, data, digestmod=sha1) h = hmac.HMAC(key, data, digestmod=hashlib.sha1)
self.assertEqual(h.hexdigest().upper(), digest.upper()) self.assertEqual(h.hexdigest().upper(), digest.upper())
shatest(b"\x0b" * 20, shatest(b"\x0b" * 20,
...@@ -75,6 +76,161 @@ class TestVectorsTestCase(unittest.TestCase): ...@@ -75,6 +76,161 @@ class TestVectorsTestCase(unittest.TestCase):
b"and Larger Than One Block-Size Data"), b"and Larger Than One Block-Size Data"),
"e8e99d0f45237d786d6bbaa7965c7808bbff1a91") "e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
def _rfc4231_test_cases(self, hashfunc):
def hmactest(key, data, hexdigests):
h = hmac.HMAC(key, data, digestmod=hashfunc)
self.assertEqual(h.hexdigest().lower(), hexdigests[hashfunc])
# 4.2. Test Case 1
hmactest(key = b'\x0b'*20,
data = b'Hi There',
hexdigests = {
hashlib.sha224: '896fb1128abbdf196832107cd49df33f'
'47b4b1169912ba4f53684b22',
hashlib.sha256: 'b0344c61d8db38535ca8afceaf0bf12b'
'881dc200c9833da726e9376c2e32cff7',
hashlib.sha384: 'afd03944d84895626b0825f4ab46907f'
'15f9dadbe4101ec682aa034c7cebc59c'
'faea9ea9076ede7f4af152e8b2fa9cb6',
hashlib.sha512: '87aa7cdea5ef619d4ff0b4241a1d6cb0'
'2379f4e2ce4ec2787ad0b30545e17cde'
'daa833b7d6b8a702038b274eaea3f4e4'
'be9d914eeb61f1702e696c203a126854',
})
# 4.3. Test Case 2
hmactest(key = b'Jefe',
data = b'what do ya want for nothing?',
hexdigests = {
hashlib.sha224: 'a30e01098bc6dbbf45690f3a7e9e6d0f'
'8bbea2a39e6148008fd05e44',
hashlib.sha256: '5bdcc146bf60754e6a042426089575c7'
'5a003f089d2739839dec58b964ec3843',
hashlib.sha384: 'af45d2e376484031617f78d2b58a6b1b'
'9c7ef464f5a01b47e42ec3736322445e'
'8e2240ca5e69e2c78b3239ecfab21649',
hashlib.sha512: '164b7a7bfcf819e2e395fbe73b56e0a3'
'87bd64222e831fd610270cd7ea250554'
'9758bf75c05a994a6d034f65f8f0e6fd'
'caeab1a34d4a6b4b636e070a38bce737',
})
# 4.4. Test Case 3
hmactest(key = b'\xaa'*20,
data = b'\xdd'*50,
hexdigests = {
hashlib.sha224: '7fb3cb3588c6c1f6ffa9694d7d6ad264'
'9365b0c1f65d69d1ec8333ea',
hashlib.sha256: '773ea91e36800e46854db8ebd09181a7'
'2959098b3ef8c122d9635514ced565fe',
hashlib.sha384: '88062608d3e6ad8a0aa2ace014c8a86f'
'0aa635d947ac9febe83ef4e55966144b'
'2a5ab39dc13814b94e3ab6e101a34f27',
hashlib.sha512: 'fa73b0089d56a284efb0f0756c890be9'
'b1b5dbdd8ee81a3655f83e33b2279d39'
'bf3e848279a722c806b485a47e67c807'
'b946a337bee8942674278859e13292fb',
})
# 4.5. Test Case 4
hmactest(key = bytes(x for x in range(0x01, 0x19+1)),
data = b'\xcd'*50,
hexdigests = {
hashlib.sha224: '6c11506874013cac6a2abc1bb382627c'
'ec6a90d86efc012de7afec5a',
hashlib.sha256: '82558a389a443c0ea4cc819899f2083a'
'85f0faa3e578f8077a2e3ff46729665b',
hashlib.sha384: '3e8a69b7783c25851933ab6290af6ca7'
'7a9981480850009cc5577c6e1f573b4e'
'6801dd23c4a7d679ccf8a386c674cffb',
hashlib.sha512: 'b0ba465637458c6990e5a8c5f61d4af7'
'e576d97ff94b872de76f8050361ee3db'
'a91ca5c11aa25eb4d679275cc5788063'
'a5f19741120c4f2de2adebeb10a298dd',
})
# 4.7. Test Case 6
hmactest(key = b'\xaa'*131,
data = b'Test Using Larger Than Block-Siz'
b'e Key - Hash Key First',
hexdigests = {
hashlib.sha224: '95e9a0db962095adaebe9b2d6f0dbce2'
'd499f112f2d2b7273fa6870e',
hashlib.sha256: '60e431591ee0b67f0d8a26aacbf5b77f'
'8e0bc6213728c5140546040f0ee37f54',
hashlib.sha384: '4ece084485813e9088d2c63a041bc5b4'
'4f9ef1012a2b588f3cd11f05033ac4c6'
'0c2ef6ab4030fe8296248df163f44952',
hashlib.sha512: '80b24263c7c1a3ebb71493c1dd7be8b4'
'9b46d1f41b4aeec1121b013783f8f352'
'6b56d037e05f2598bd0fd2215d6a1e52'
'95e64f73f63f0aec8b915a985d786598',
})
# 4.8. Test Case 7
hmactest(key = b'\xaa'*131,
data = b'This is a test using a larger th'
b'an block-size key and a larger t'
b'han block-size data. The key nee'
b'ds to be hashed before being use'
b'd by the HMAC algorithm.',
hexdigests = {
hashlib.sha224: '3a854166ac5d9f023f54d517d0b39dbd'
'946770db9c2b95c9f6f565d1',
hashlib.sha256: '9b09ffa71b942fcb27635fbcd5b0e944'
'bfdc63644f0713938a7f51535c3a35e2',
hashlib.sha384: '6617178e941f020d351e2f254e8fd32c'
'602420feb0b8fb9adccebb82461e99c5'
'a678cc31e799176d3860e6110c46523e',
hashlib.sha512: 'e37b6a775dc87dbaa4dfa9f96e5e3ffd'
'debd71f8867289865df5a32d20cdc944'
'b6022cac3c4982b10d5eeb55c3e4de15'
'134676fb6de0446065c97440fa8c6a58',
})
def test_sha224_rfc4231(self):
self._rfc4231_test_cases(hashlib.sha224)
def test_sha256_rfc4231(self):
self._rfc4231_test_cases(hashlib.sha256)
def test_sha384_rfc4231(self):
self._rfc4231_test_cases(hashlib.sha384)
def test_sha512_rfc4231(self):
self._rfc4231_test_cases(hashlib.sha512)
def test_legacy_block_size_warnings(self):
class MockCrazyHash(object):
"""Ain't no block_size attribute here."""
def __init__(self, *args):
self._x = hashlib.sha1(*args)
self.digest_size = self._x.digest_size
def update(self, v):
self._x.update(v)
def digest(self):
return self._x.digest()
warnings.simplefilter('error', RuntimeWarning)
try:
try:
hmac.HMAC(b'a', b'b', digestmod=MockCrazyHash)
except RuntimeWarning:
pass
else:
self.fail('Expected warning about missing block_size')
MockCrazyHash.block_size = 1
try:
hmac.HMAC(b'a', b'b', digestmod=MockCrazyHash)
except RuntimeWarning:
pass
else:
self.fail('Expected warning about small block_size')
finally:
warnings.resetwarnings()
class ConstructorTestCase(unittest.TestCase): class ConstructorTestCase(unittest.TestCase):
...@@ -95,9 +251,8 @@ class ConstructorTestCase(unittest.TestCase): ...@@ -95,9 +251,8 @@ class ConstructorTestCase(unittest.TestCase):
def test_withmodule(self): def test_withmodule(self):
# Constructor call with text and digest module. # Constructor call with text and digest module.
from hashlib import sha1
try: try:
h = hmac.HMAC(b"key", b"", sha1) h = hmac.HMAC(b"key", b"", hashlib.sha1)
except: except:
self.fail("Constructor call with hashlib.sha1 raised exception.") self.fail("Constructor call with hashlib.sha1 raised exception.")
...@@ -106,7 +261,6 @@ class SanityTestCase(unittest.TestCase): ...@@ -106,7 +261,6 @@ class SanityTestCase(unittest.TestCase):
def test_default_is_md5(self): def test_default_is_md5(self):
# Testing if HMAC defaults to MD5 algorithm. # Testing if HMAC defaults to MD5 algorithm.
# NOTE: this whitebox test depends on the hmac class internals # NOTE: this whitebox test depends on the hmac class internals
import hashlib
h = hmac.HMAC(b"key") h = hmac.HMAC(b"key")
self.assertEqual(h.digest_cons, hashlib.md5) self.assertEqual(h.digest_cons, hashlib.md5)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment