Kaydet (Commit) 127b461b authored tarafından Aymeric Augustin's avatar Aymeric Augustin

[py3] Ported django.utils.crypto.

üst b55e0777
...@@ -50,7 +50,7 @@ def salted_hmac(key_salt, value, secret=None): ...@@ -50,7 +50,7 @@ def salted_hmac(key_salt, value, secret=None):
# line is redundant and could be replaced by key = key_salt + secret, since # line is redundant and could be replaced by key = key_salt + secret, since
# the hmac module does the same thing for keys longer than the block size. # the hmac module does the same thing for keys longer than the block size.
# However, we need to ensure that we *always* do this. # However, we need to ensure that we *always* do this.
return hmac.new(key, msg=value, digestmod=hashlib.sha1) return hmac.new(key, msg=smart_bytes(value), digestmod=hashlib.sha1)
def get_random_string(length=12, def get_random_string(length=12,
...@@ -99,7 +99,7 @@ def _bin_to_long(x): ...@@ -99,7 +99,7 @@ def _bin_to_long(x):
This is a clever optimization for fast xor vector math This is a clever optimization for fast xor vector math
""" """
return int(x.encode('hex'), 16) return int(binascii.hexlify(x), 16)
def _long_to_bin(x, hex_format_string): def _long_to_bin(x, hex_format_string):
...@@ -112,13 +112,14 @@ def _long_to_bin(x, hex_format_string): ...@@ -112,13 +112,14 @@ def _long_to_bin(x, hex_format_string):
def _fast_hmac(key, msg, digest): def _fast_hmac(key, msg, digest):
""" """
A trimmed down version of Python's HMAC implementation A trimmed down version of Python's HMAC implementation.
This function operates on bytes.
""" """
dig1, dig2 = digest(), digest() dig1, dig2 = digest(), digest()
key = smart_bytes(key)
if len(key) > dig1.block_size: if len(key) > dig1.block_size:
key = digest(key).digest() key = digest(key).digest()
key += chr(0) * (dig1.block_size - len(key)) key += b'\x00' * (dig1.block_size - len(key))
dig1.update(key.translate(_trans_36)) dig1.update(key.translate(_trans_36))
dig1.update(msg) dig1.update(msg)
dig2.update(key.translate(_trans_5c)) dig2.update(key.translate(_trans_5c))
......
from __future__ import unicode_literals
import binascii
import math import math
import timeit import timeit
import hashlib import hashlib
...@@ -108,15 +110,15 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase): ...@@ -108,15 +110,15 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase):
"c4007d5298f9033c0241d5ab69305e7b64eceeb8d" "c4007d5298f9033c0241d5ab69305e7b64eceeb8d"
"834cfec"), "834cfec"),
}, },
# Check leading zeros are not stripped (#17481) # Check leading zeros are not stripped (#17481)
{ {
"args": { "args": {
"password": chr(186), "password": b'\xba',
"salt": "salt", "salt": "salt",
"iterations": 1, "iterations": 1,
"dklen": 20, "dklen": 20,
"digest": hashlib.sha1, "digest": hashlib.sha1,
}, },
"result": '0053d3b91a7f1e54effebd6d68771e8a6e0b2c5b', "result": '0053d3b91a7f1e54effebd6d68771e8a6e0b2c5b',
}, },
] ]
...@@ -124,12 +126,14 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase): ...@@ -124,12 +126,14 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase):
def test_public_vectors(self): def test_public_vectors(self):
for vector in self.rfc_vectors: for vector in self.rfc_vectors:
result = pbkdf2(**vector['args']) result = pbkdf2(**vector['args'])
self.assertEqual(result.encode('hex'), vector['result']) self.assertEqual(binascii.hexlify(result).decode('ascii'),
vector['result'])
def test_regression_vectors(self): def test_regression_vectors(self):
for vector in self.regression_vectors: for vector in self.regression_vectors:
result = pbkdf2(**vector['args']) result = pbkdf2(**vector['args'])
self.assertEqual(result.encode('hex'), vector['result']) self.assertEqual(binascii.hexlify(result).decode('ascii'),
vector['result'])
def test_performance_scalability(self): def test_performance_scalability(self):
""" """
...@@ -140,11 +144,11 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase): ...@@ -140,11 +144,11 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase):
# to run the test suite and false positives caused by imprecise # to run the test suite and false positives caused by imprecise
# measurement. # measurement.
n1, n2 = 200000, 800000 n1, n2 = 200000, 800000
elapsed = lambda f: timeit.Timer(f, elapsed = lambda f: timeit.Timer(f,
'from django.utils.crypto import pbkdf2').timeit(number=1) 'from django.utils.crypto import pbkdf2').timeit(number=1)
t1 = elapsed('pbkdf2("password", "salt", iterations=%d)' % n1) t1 = elapsed('pbkdf2("password", "salt", iterations=%d)' % n1)
t2 = elapsed('pbkdf2("password", "salt", iterations=%d)' % n2) t2 = elapsed('pbkdf2("password", "salt", iterations=%d)' % n2)
measured_scale_exponent = math.log(t2 / t1, n2 / n1) measured_scale_exponent = math.log(t2 / t1, n2 / n1)
# This should be less than 1. We allow up to 1.2 so that tests don't # This should be less than 1. We allow up to 1.2 so that tests don't
# fail nondeterministically too often. # fail nondeterministically too often.
self.assertLess(measured_scale_exponent, 1.2) self.assertLess(measured_scale_exponent, 1.2)
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