python passlib: what is the best value for “rounds”

后端 未结 1 1818
北荒
北荒 2020-12-28 23:37

from the passlib documentation

For most public facing services, you can generally have signin take upwards of 250ms - 400ms before users start getting

相关标签:
1条回答
  • 2020-12-29 00:04

    (passlib developer here)

    The amount of time pbkdf2_sha512 takes is linearly proportional to it's rounds parameter (elapsed_time = rounds * native_speed). Using the data for your system, native_speed = 12000 / .143 = 83916 iterations/second, which means you'll need around 83916 * .350 = 29575 rounds to get ~350ms delay.

    Things are a little tricker for bcrypt, because the amount of time it takes is logarithmically proportional to it's rounds parameter (elapsed_time = (2 ** rounds) * native_speed). Using the data for your system, native_speed = (2 ** 12) / .405 = 10113 iterations/second, which means you'll need around log(10113 * .350, 2) = 11.79 rounds to get ~350 ms delay. But since BCrypt only accepts integer rounds parameters, so you'll need to pick rounds=11 (~200ms) or rounds=12 (~400ms).


    All of this is something I'm hoping to fix in a future release of passlib. As a work in progress, passlib's mercurial repo currently contains a simple little script, choose_rounds.py, which takes care of choosing the correct rounds value for a given target time. You can download and run it directly as follows (it may take 20s or so to run):

    $ python choose_rounds.py -h
    usage: python choose_rounds.py <hash_name> [<target_in_milliseconds>]
    
    $ python choose_rounds.py pbkdf2_sha512 350
    hash............: pbkdf2_sha512
    speed...........: 83916 iterations/second
    target time.....: 350 ms
    target rounds...: 29575  
    
    $ python choose_rounds.py bcrypt 350
    hash............: bcrypt
    speed...........: 10113 iterations/second
    target time.....: 350 ms
    target rounds...: 11 (200ms -- 150ms faster than requested)
    target rounds...: 12 (400ms -- 50ms slower than requested)
    

    (edit: added response regarding secure minimum rounds...)

    Disclaimer: Determining a secure minimum is a surprisingly tricky question - there are a number of hard to quantify parameters, very little real world data, and some rigorously unhelpful theory. Lacking a good authority, I've been researching the topic myself; and for off-the-cuff calculations, I've boiled the raw data down to a short formula (below), which is generally what I use. Just be aware that behind it are a couple of pages of assumptions and rough estimates, making it more of a Fermi Estimation than an exact answer :|

    My rule of thumb (mid 2012) for attacking PBKDF2-HMAC-SHA512 using GPUs is:

     days * dollars = 2**(n-31) * rounds
    
    • days is the number of days before the attacker has a 50/50 chance of guessing the password.
    • dollars is the attackers' hardware budget (in $USD).
    • n is the average amount of entropy in your user's passwords (in bits).

    To answer your script-kiddie question: if an average password has 32 bits of entropy, and the attacker has a $2000 system with a good GPU, then at 30000 rounds they will need 30 days (2**(32-31)*30000/2000) to have a 50/50 chance of cracking a given hash. I'd recommend playing around with the values until you arrive at a rounds/days tradeoff that you're comfortable with.

    Some things to keep in mind:

    • The success rate of a dictionary attack isn't linear, it's more of "long tail" situation, so think of the 50/50 mark as more of a half-life.

    • That 31 is the key factor, as it encodes an estimation of the cost of attacking a specific algorithm using a specific technology level. The actual value, 2**-31, measures the "dollar-days per round" it will cost an attacker. For comparison, attacking PBKDF2-HMAC-SHA512 using an ASIC has a factor closer to 46 -- larger numbers mean more bang for the attacker's buck, and less security per round for you, though script kiddies generally won't have that kind of budget :)

    0 讨论(0)
提交回复
热议问题