codekingpro/portable-devtools
114k
1"""passlib.pbkdf2 - PBKDF2 support2 3this module is getting increasingly poorly named.4maybe rename to "kdf" since it's getting more key derivation functions added.5"""6#=============================================================================7# imports8#=============================================================================9from __future__ import division10# core11import logging; log = logging.getLogger(__name__)12# site13# pkg14from passlib.exc import ExpectedTypeError15from passlib.utils.decor import deprecated_function16from passlib.utils.compat import native_string_types17from passlib.crypto.digest import norm_hash_name, lookup_hash, pbkdf1 as _pbkdf1, pbkdf2_hmac, compile_hmac18# local19__all__ = [20 # hash utils21 "norm_hash_name",22 23 # prf utils24 "get_prf",25 26 # kdfs27 "pbkdf1",28 "pbkdf2",29]30 31#=============================================================================32# issue deprecation warning for module33#=============================================================================34from warnings import warn35 36warn("the module 'passlib.utils.pbkdf2' is deprecated as of Passlib 1.7, "37 "and will be removed in Passlib 2.0, please use 'passlib.crypto' instead",38 DeprecationWarning)39 40#=============================================================================41# hash helpers42#=============================================================================43 44norm_hash_name = deprecated_function(deprecated="1.7", removed="1.8", func_module=__name__,45 replacement="passlib.crypto.digest.norm_hash_name")(norm_hash_name)46 47#=============================================================================48# prf lookup49#=============================================================================50 51#: cache mapping prf name/func -> (func, digest_size)52_prf_cache = {}53 54#: list of accepted prefixes55_HMAC_PREFIXES = ("hmac_", "hmac-")56 57def get_prf(name):58 """Lookup pseudo-random family (PRF) by name.59 60 :arg name:61 This must be the name of a recognized prf.62 Currently this only recognizes names with the format63 :samp:`hmac-{digest}`, where :samp:`{digest}`64 is the name of a hash function such as65 ``md5``, ``sha256``, etc.66 67 todo: restore text about callables.68 69 :raises ValueError: if the name is not known70 :raises TypeError: if the name is not a callable or string71 72 :returns:73 a tuple of :samp:`({prf_func}, {digest_size})`, where:74 75 * :samp:`{prf_func}` is a function implementing76 the specified PRF, and has the signature77 ``prf_func(secret, message) -> digest``.78 79 * :samp:`{digest_size}` is an integer indicating80 the number of bytes the function returns.81 82 Usage example::83 84 >>> from passlib.utils.pbkdf2 import get_prf85 >>> hmac_sha256, dsize = get_prf("hmac-sha256")86 >>> hmac_sha25687 <function hmac_sha256 at 0x1e37c80>88 >>> dsize89 3290 >>> digest = hmac_sha256('password', 'message')91 92 .. deprecated:: 1.793 94 This function is deprecated, and will be removed in Passlib 2.0.95 This only related replacement is :func:`passlib.crypto.digest.compile_hmac`.96 """97 global _prf_cache98 if name in _prf_cache:99 return _prf_cache[name]100 if isinstance(name, native_string_types):101 if not name.startswith(_HMAC_PREFIXES):102 raise ValueError("unknown prf algorithm: %r" % (name,))103 digest = lookup_hash(name[5:]).name104 def hmac(key, msg):105 return compile_hmac(digest, key)(msg)106 record = (hmac, hmac.digest_info.digest_size)107 elif callable(name):108 # assume it's a callable, use it directly109 digest_size = len(name(b'x', b'y'))110 record = (name, digest_size)111 else:112 raise ExpectedTypeError(name, "str or callable", "prf name")113 _prf_cache[name] = record114 return record115 116#=============================================================================117# pbkdf1 support118#=============================================================================119def pbkdf1(secret, salt, rounds, keylen=None, hash="sha1"):120 """pkcs#5 password-based key derivation v1.5121 122 :arg secret: passphrase to use to generate key123 :arg salt: salt string to use when generating key124 :param rounds: number of rounds to use to generate key125 :arg keylen: number of bytes to generate (if ``None``, uses digest's native size)126 :param hash:127 hash function to use. must be name of a hash recognized by hashlib.128 129 :returns:130 raw bytes of generated key131 132 .. note::133 134 This algorithm has been deprecated, new code should use PBKDF2.135 Among other limitations, ``keylen`` cannot be larger136 than the digest size of the specified hash.137 138 .. deprecated:: 1.7139 140 This has been relocated to :func:`passlib.crypto.digest.pbkdf1`,141 and this version will be removed in Passlib 2.0.142 *Note the call signature has changed.*143 """144 return _pbkdf1(hash, secret, salt, rounds, keylen)145 146#=============================================================================147# pbkdf2148#=============================================================================149def pbkdf2(secret, salt, rounds, keylen=None, prf="hmac-sha1"):150 """pkcs#5 password-based key derivation v2.0151 152 :arg secret:153 passphrase to use to generate key154 155 :arg salt:156 salt string to use when generating key157 158 :param rounds:159 number of rounds to use to generate key160 161 :arg keylen:162 number of bytes to generate.163 if set to ``None``, will use digest size of selected prf.164 165 :param prf:166 psuedo-random family to use for key strengthening.167 this must be a string starting with ``"hmac-"``, followed by the name of a known digest.168 this defaults to ``"hmac-sha1"`` (the only prf explicitly listed in169 the PBKDF2 specification)170 171 .. rst-class:: warning172 173 .. versionchanged 1.7:174 175 This argument no longer supports arbitrary PRF callables --176 These were rarely / never used, and created too many unwanted codepaths.177 178 :returns:179 raw bytes of generated key180 181 .. deprecated:: 1.7182 183 This has been deprecated in favor of :func:`passlib.crypto.digest.pbkdf2_hmac`,184 and will be removed in Passlib 2.0. *Note the call signature has changed.*185 """186 if callable(prf) or (isinstance(prf, native_string_types) and not prf.startswith(_HMAC_PREFIXES)):187 raise NotImplementedError("non-HMAC prfs are not supported as of Passlib 1.7")188 digest = prf[5:]189 return pbkdf2_hmac(digest, secret, salt, rounds, keylen)190 191#=============================================================================192# eof193#=============================================================================194 