Warn upon too few bcrypt.kdf() rounds (#104)

* Warn upon too few bcrypt.kdf() rounds

* Use warings library instead of sys.stderr

* Add test for changes

* Test new kdf parameter for coverage

* Formatting & py26 compatibility
This commit is contained in:
Luc Gommans 2017-01-21 14:53:09 +01:00 committed by Paul Kehrer
parent 717fe63db6
commit 4b8c73ac78
2 changed files with 25 additions and 1 deletions

View File

@ -18,6 +18,7 @@ from __future__ import division
import os
import re
import warnings
import six
@ -112,7 +113,7 @@ def checkpw(password, hashed_password):
return _bcrypt.lib.timingsafe_bcmp(ret, hashed_password, len(ret)) == 0
def kdf(password, salt, desired_key_bytes, rounds):
def kdf(password, salt, desired_key_bytes, rounds, ignore_few_rounds=False):
if isinstance(password, six.text_type) or isinstance(salt, six.text_type):
raise TypeError("Unicode-objects must be encoded before hashing")
@ -125,6 +126,16 @@ def kdf(password, salt, desired_key_bytes, rounds):
if rounds < 1:
raise ValueError("rounds must be 1 or more")
if rounds < 50 and not ignore_few_rounds:
# They probably think bcrypt.kdf()'s rounds parameter is logarithmic,
# expecting this value to be slow enough (it probably would be if this
# were bcrypt). Emit a warning.
warnings.warn((
"Warning: bcrypt.kdf() called with only {0} round(s). "
"This few is not secure: the parameter is linear, like PBKDF2.")
.format(rounds),
UserWarning)
key = _bcrypt.ffi.new("uint8_t[]", desired_key_bytes)
res = _bcrypt.lib.bcrypt_pbkdf(
password, len(password), salt, len(salt), key, len(key), rounds

View File

@ -418,6 +418,19 @@ def test_kdf_str_salt():
)
def test_kdf_no_warn_rounds():
bcrypt.kdf(
b"password", b"salt", 10, 10, True
)
def test_kdf_warn_rounds():
with pytest.warns(UserWarning):
bcrypt.kdf(
b"password", b"salt", 10, 10
)
@pytest.mark.parametrize(
("password", "salt", "desired_key_bytes", "rounds", "error"),
[