|
65 | 65 | algorithms_available = set(__always_supported) |
66 | 66 |
|
67 | 67 | __all__ = __always_supported + ('new', 'algorithms_guaranteed', |
68 | | - 'algorithms_available', 'pbkdf2_hmac', 'file_digest') |
| 68 | + 'algorithms_available', 'file_digest') |
69 | 69 |
|
70 | 70 |
|
71 | 71 | __builtin_constructor_cache = {} |
@@ -180,72 +180,10 @@ def __hash_new(name, data=b'', **kwargs): |
180 | 180 | try: |
181 | 181 | # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA |
182 | 182 | from _hashlib import pbkdf2_hmac |
| 183 | + __all__ += ('pbkdf2_hmac',) |
183 | 184 | except ImportError: |
184 | | - from warnings import warn as _warn |
185 | | - _trans_5C = bytes((x ^ 0x5C) for x in range(256)) |
186 | | - _trans_36 = bytes((x ^ 0x36) for x in range(256)) |
187 | | - |
188 | | - def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None): |
189 | | - """Password based key derivation function 2 (PKCS #5 v2.0) |
190 | | -
|
191 | | - This Python implementations based on the hmac module about as fast |
192 | | - as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster |
193 | | - for long passwords. |
194 | | - """ |
195 | | - _warn( |
196 | | - "Python implementation of pbkdf2_hmac() is deprecated.", |
197 | | - category=DeprecationWarning, |
198 | | - stacklevel=2 |
199 | | - ) |
200 | | - if not isinstance(hash_name, str): |
201 | | - raise TypeError(hash_name) |
202 | | - |
203 | | - if not isinstance(password, (bytes, bytearray)): |
204 | | - password = bytes(memoryview(password)) |
205 | | - if not isinstance(salt, (bytes, bytearray)): |
206 | | - salt = bytes(memoryview(salt)) |
207 | | - |
208 | | - # Fast inline HMAC implementation |
209 | | - inner = new(hash_name) |
210 | | - outer = new(hash_name) |
211 | | - blocksize = getattr(inner, 'block_size', 64) |
212 | | - if len(password) > blocksize: |
213 | | - password = new(hash_name, password).digest() |
214 | | - password = password + b'\x00' * (blocksize - len(password)) |
215 | | - inner.update(password.translate(_trans_36)) |
216 | | - outer.update(password.translate(_trans_5C)) |
217 | | - |
218 | | - def prf(msg, inner=inner, outer=outer): |
219 | | - # PBKDF2_HMAC uses the password as key. We can re-use the same |
220 | | - # digest objects and just update copies to skip initialization. |
221 | | - icpy = inner.copy() |
222 | | - ocpy = outer.copy() |
223 | | - icpy.update(msg) |
224 | | - ocpy.update(icpy.digest()) |
225 | | - return ocpy.digest() |
226 | | - |
227 | | - if iterations < 1: |
228 | | - raise ValueError(iterations) |
229 | | - if dklen is None: |
230 | | - dklen = outer.digest_size |
231 | | - if dklen < 1: |
232 | | - raise ValueError(dklen) |
233 | | - |
234 | | - dkey = b'' |
235 | | - loop = 1 |
236 | | - from_bytes = int.from_bytes |
237 | | - while len(dkey) < dklen: |
238 | | - prev = prf(salt + loop.to_bytes(4)) |
239 | | - # endianness doesn't matter here as long to / from use the same |
240 | | - rkey = from_bytes(prev) |
241 | | - for i in range(iterations - 1): |
242 | | - prev = prf(prev) |
243 | | - # rkey = rkey ^ prev |
244 | | - rkey ^= from_bytes(prev) |
245 | | - loop += 1 |
246 | | - dkey += rkey.to_bytes(inner.digest_size) |
247 | | - |
248 | | - return dkey[:dklen] |
| 185 | + pass |
| 186 | + |
249 | 187 |
|
250 | 188 | try: |
251 | 189 | # OpenSSL's scrypt requires OpenSSL 1.1+ |
|
0 commit comments