• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# $Id$
2#
3#  Copyright (C) 2005   Gregory P. Smith (greg@krypto.org)
4#  Licensed to PSF under a Contributor Agreement.
5#
6
7__doc__ = """hashlib module - A common interface to many hash functions.
8
9new(name, string='') - returns a new hash object implementing the
10                       given hash function; initializing the hash
11                       using the given string data.
12
13Named constructor functions are also available, these are much faster
14than using new():
15
16md5(), sha1(), sha224(), sha256(), sha384(), and sha512()
17
18More algorithms may be available on your platform but the above are guaranteed
19to exist.  See the algorithms_guaranteed and algorithms_available attributes
20to find out what algorithm names can be passed to new().
21
22NOTE: If you want the adler32 or crc32 hash functions they are available in
23the zlib module.
24
25Choose your hash function wisely.  Some have known collision weaknesses.
26sha384 and sha512 will be slow on 32 bit platforms.
27
28Hash objects have these methods:
29 - update(arg): Update the hash object with the string arg. Repeated calls
30                are equivalent to a single call with the concatenation of all
31                the arguments.
32 - digest():    Return the digest of the strings passed to the update() method
33                so far. This may contain non-ASCII characters, including
34                NUL bytes.
35 - hexdigest(): Like digest() except the digest is returned as a string of
36                double length, containing only hexadecimal digits.
37 - copy():      Return a copy (clone) of the hash object. This can be used to
38                efficiently compute the digests of strings that share a common
39                initial substring.
40
41For example, to obtain the digest of the string 'Nobody inspects the
42spammish repetition':
43
44    >>> import hashlib
45    >>> m = hashlib.md5()
46    >>> m.update("Nobody inspects")
47    >>> m.update(" the spammish repetition")
48    >>> m.digest()
49    '\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
50
51More condensed:
52
53    >>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
54    'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
55
56"""
57
58# This tuple and __get_builtin_constructor() must be modified if a new
59# always available algorithm is added.
60__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
61
62algorithms_guaranteed = set(__always_supported)
63algorithms_available = set(__always_supported)
64
65algorithms = __always_supported
66
67__all__ = __always_supported + ('new', 'algorithms_guaranteed',
68                                'algorithms_available', 'algorithms',
69                                'pbkdf2_hmac')
70
71
72def __get_builtin_constructor(name):
73    try:
74        if name in ('SHA1', 'sha1'):
75            import _sha
76            return _sha.new
77        elif name in ('MD5', 'md5'):
78            import _md5
79            return _md5.new
80        elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'):
81            import _sha256
82            bs = name[3:]
83            if bs == '256':
84                return _sha256.sha256
85            elif bs == '224':
86                return _sha256.sha224
87        elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'):
88            import _sha512
89            bs = name[3:]
90            if bs == '512':
91                return _sha512.sha512
92            elif bs == '384':
93                return _sha512.sha384
94    except ImportError:
95        pass  # no extension module, this hash is unsupported.
96
97    raise ValueError('unsupported hash type ' + name)
98
99
100def __get_openssl_constructor(name):
101    try:
102        f = getattr(_hashlib, 'openssl_' + name)
103        # Allow the C module to raise ValueError.  The function will be
104        # defined but the hash not actually available thanks to OpenSSL.
105        f()
106        # Use the C function directly (very fast)
107        return f
108    except (AttributeError, ValueError):
109        return __get_builtin_constructor(name)
110
111
112def __py_new(name, string=''):
113    """new(name, string='') - Return a new hashing object using the named algorithm;
114    optionally initialized with a string.
115    """
116    return __get_builtin_constructor(name)(string)
117
118
119def __hash_new(name, string=''):
120    """new(name, string='') - Return a new hashing object using the named algorithm;
121    optionally initialized with a string.
122    """
123    try:
124        return _hashlib.new(name, string)
125    except ValueError:
126        # If the _hashlib module (OpenSSL) doesn't support the named
127        # hash, try using our builtin implementations.
128        # This allows for SHA224/256 and SHA384/512 support even though
129        # the OpenSSL library prior to 0.9.8 doesn't provide them.
130        return __get_builtin_constructor(name)(string)
131
132
133try:
134    import _hashlib
135    new = __hash_new
136    __get_hash = __get_openssl_constructor
137    algorithms_available = algorithms_available.union(
138        _hashlib.openssl_md_meth_names)
139except ImportError:
140    new = __py_new
141    __get_hash = __get_builtin_constructor
142
143for __func_name in __always_supported:
144    # try them all, some may not work due to the OpenSSL
145    # version not supporting that algorithm.
146    try:
147        globals()[__func_name] = __get_hash(__func_name)
148    except ValueError:
149        import logging
150        logging.exception('code for hash %s was not found.', __func_name)
151
152
153try:
154    # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA
155    from _hashlib import pbkdf2_hmac
156except ImportError:
157    import binascii
158    import struct
159
160    _trans_5C = b"".join(chr(x ^ 0x5C) for x in range(256))
161    _trans_36 = b"".join(chr(x ^ 0x36) for x in range(256))
162
163    def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None):
164        """Password based key derivation function 2 (PKCS #5 v2.0)
165
166        This Python implementations based on the hmac module about as fast
167        as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster
168        for long passwords.
169        """
170        if not isinstance(hash_name, str):
171            raise TypeError(hash_name)
172
173        if not isinstance(password, (bytes, bytearray)):
174            password = bytes(buffer(password))
175        if not isinstance(salt, (bytes, bytearray)):
176            salt = bytes(buffer(salt))
177
178        # Fast inline HMAC implementation
179        inner = new(hash_name)
180        outer = new(hash_name)
181        blocksize = getattr(inner, 'block_size', 64)
182        if len(password) > blocksize:
183            password = new(hash_name, password).digest()
184        password = password + b'\x00' * (blocksize - len(password))
185        inner.update(password.translate(_trans_36))
186        outer.update(password.translate(_trans_5C))
187
188        def prf(msg, inner=inner, outer=outer):
189            # PBKDF2_HMAC uses the password as key. We can re-use the same
190            # digest objects and just update copies to skip initialization.
191            icpy = inner.copy()
192            ocpy = outer.copy()
193            icpy.update(msg)
194            ocpy.update(icpy.digest())
195            return ocpy.digest()
196
197        if iterations < 1:
198            raise ValueError(iterations)
199        if dklen is None:
200            dklen = outer.digest_size
201        if dklen < 1:
202            raise ValueError(dklen)
203
204        hex_format_string = "%%0%ix" % (new(hash_name).digest_size * 2)
205
206        dkey = b''
207        loop = 1
208        while len(dkey) < dklen:
209            prev = prf(salt + struct.pack(b'>I', loop))
210            rkey = int(binascii.hexlify(prev), 16)
211            for i in xrange(iterations - 1):
212                prev = prf(prev)
213                rkey ^= int(binascii.hexlify(prev), 16)
214            loop += 1
215            dkey += binascii.unhexlify(hex_format_string % rkey)
216
217        return dkey[:dklen]
218
219# Cleanup locals()
220del __always_supported, __func_name, __get_hash
221del __py_new, __hash_new, __get_openssl_constructor
222