Hi
I just opened the vote for the "Increasing the default BCrypt cost" RFC.
The RFC contains a two votes, one primary vote that requires a 2/3
majority to pass and a secondary vote deciding on the new costs with a
simple majority. Voting runs 2 weeks until 2023-10-05 17:45 UTC.
Please find the following resources for your references:
RFC Text: https://wiki.php.net/rfc/bcrypt_cost_2023
Discussion Thread: https://externals.io/message/121004
Feedback by a Hashcat team member on Fediverse:
https://phpc.social/@tychotithonus@infosec.exchange/111025157601179075
Best regards
Tim Düsterhus
Hi
I just opened the vote for the "Increasing the default BCrypt cost" RFC.
The RFC contains a two votes, one primary vote that requires a 2/3
majority to pass and a secondary vote deciding on the new costs with a
simple majority. Voting runs 2 weeks until 2023-10-05 17:45 UTC.
I'd like to clarify that in case of a tie for the secondary vote, I'll
break the tie in favor of 11 as the more conservative choice. I hope
that the results will be clear, though :-)
Best regards
Tim Düsterhus
Le 21/09/2023 à 19:26, Tim Düsterhus a écrit :
Hi
I just opened the vote for the "Increasing the default BCrypt cost" RFC.
The RFC contains a two votes, one primary vote that requires a 2/3
majority to pass and a secondary vote deciding on the new costs with a
simple majority. Voting runs 2 weeks until 2023-10-05 17:45 UTC.Please find the following resources for your references:
Tested on ARM (Neoverse-N1)
Cost 9: 5.175103 total (0.051751 per hash)
Cost 10: 10.325875 total (0.103259 per hash)
Cost 11: 20.627759 total (0.206278 per hash)
Cost 12: 41.231114 total (0.412311 per hash)
Cost 13: 82.437880 total (0.824379 per hash)
Cost 14: 164.851835 total (1.648518 per hash)
So 11 seems reasonable.
Remi
RFC Text: https://wiki.php.net/rfc/bcrypt_cost_2023
Discussion Thread: https://externals.io/message/121004
Feedback by a Hashcat team member on Fediverse:
https://phpc.social/@tychotithonus@infosec.exchange/111025157601179075Best regards
Tim Düsterhus
more results on ARM:
RK3399 - Cortex-A7x
Cost 10: 10.694221 total (0.106942 per hash)
Cost 11: 21.360409 total (0.213604 per hash)
Cost 12: 42.692786 total (0.426928 per hash)
RK3399 - Cortex-A5x
Cost 10: 15.146773 total (0.151468 per hash)
Cost 11: 30.272059 total (0.302721 per hash)
Cost 12: 60.607128 total (0.606071 per hash)
Ampere Altra
Cost 10: 6.286994 total (0.062870 per hash)
Cost 11: 13.056349 total (0.130563 per hash)
Cost 12: 25.230312 total (0.252303 per hash)
I just opened the vote for the "Increasing the default BCrypt cost" RFC.
The RFC contains a two votes, one primary vote that requires a 2/3
majority to pass and a secondary vote deciding on the new costs with a
simple majority. Voting runs 2 weeks until 2023-10-05 17:45 UTC.Please find the following resources for your references:
RFC Text: https://wiki.php.net/rfc/bcrypt_cost_2023
Discussion Thread: https://externals.io/message/121004
Feedback by a Hashcat team member on Fediverse:
https://phpc.social/@tychotithonus@infosec.exchange/111025157601179075
Hi Tim,
For the record, I voted for 11 because I think it's nicer to end users (I
guess many don't know they could have a potential DoS vector via password
submissions), and also because it's going to be easy to raise again in
8.5/9.0.
I was wondering if you considered also raising the Argon2 default cost? Has
this been discussed?
Thanks for the RFC
Nicolas
Hi
For the record, I voted for 11 because I think it's nicer to end users (I
guess many don't know they could have a potential DoS vector via password
submissions), and also because it's going to be easy to raise again in
8.5/9.0.I was wondering if you considered also raising the Argon2 default cost? Has
this been discussed?
I did not consider this, because I don't have sufficient knowledge about
Argon2's behavior to write up a proper RFC for that without spreading
misinformation. For the reasons mentioned in
https://news-web.php.net/php.internals/120996, I do not use Argon2 myself.
See also this comment for further information:
https://github.com/laravel/laravel/pull/6245#issuecomment-1730504804 and
the Fediverse thread I linked in the initial email opening the vote.
Best regards
Tim Düsterhus
For the record, I voted for 11 because I think it's nicer to end users (I guess many don't know they could have a potential DoS vector via password submissions), and also because it's going to be easy to raise again in 8.5/9.0.
+1
I can't vote, but I would urge people to be careful with this.
While a high cost might make you feel good, the DoS problem is real, especially on older hardware - 10 is still fine today, 11 is a fair improvement against brute force guessing, 12 is just burning CPU cycles today, simply because the difference does not address the problem of commonly used passwords (like 123456, password1, monkey, etc).
Also, if you want to increase the cost yourself, on a system which blocks too many password attempts, you can do that easily - this is about the default, for people who are not customising it for their (shared/old) hardware.
Craig,
OWASP Bristol chapter leader, and regular attendee of PasswordsCon.
Hi
For the record, I voted for 11 because I think it's nicer to end users (I guess many don't know they could have a potential DoS vector via password submissions), and also because it's going to be easy to raise again in 8.5/9.0.
[...]
I can't vote, but I would urge people to be careful with this.
I've now did the maths and you really need rate limiting no matter if
you use costs 10, 11 or 12, so I believe the DoS argument is a little moot.
Taking the Xeon(R) E-2246G CPU as the fastest CPU within the RFC itself
(only beaten by Alexandru's Xeon Gold 5416S):
Verifying a single cost-11 hash keeps a single core busy for ~80ms. This
allows for calculating 12.7 cost-11 hashes per core and second. The CPU
is a 6C/12T CPU. SMT likely does not provide a performance benefit,
because the cores will generally be busy all the time, but let's just
assume SMT scales linearly for sake of the argument. Rounding up
generously that means this CPU can calculate ~155 cost-11 hashes per second.
A single computer on a slow Internet connection is easily capable of
sustaining 155 HTTP requests per second. For reference a single HTTP/2
TCP connection commonly allows for 100 concurrent streams as per
https://stackoverflow.com/a/36847527/782822.
The current costs of 10 would allow for roughly twice the amount of
hashes per second, resulting in the CPU being saturated at just 300
requests per second, still easily emitted with a single low-bandwidth
computer.
For the Xeon Gold 5416S which needs 0.1s / cost-12 hash (i.e. 50ms per
cost-11 hash) you can do 20 cost-11 hashes per core and second. This CPU
has 16C/32T, resulting in less than 640 hashes per second if you assume
SMT scales linearly.
While a high cost might make you feel good, the DoS problem is real, especially on older hardware - 10 is still fine today, 11 is a fair improvement against brute force guessing, 12 is just burning CPU cycles today, simply because the difference does not address the problem of commonly used passwords (like 123456, password1, monkey, etc).
The attacker does not know which users use less secure passwords and
thus will spend effort for "secure" and "insecure" passwords alike.
Doubling the costs will mean that each password takes twice as long to
crack on average, making cracking twice as expensive. For less secure
passwords that can make the difference between "being cracked" and "not
being cracked" if the attacker is willing to spend a given amount of CPU
time per password.
Also, if you want to increase the cost yourself, on a system which blocks too many password attempts, you can do that easily - this is about the default, for people who are not customising it for their (shared/old) hardware.
I believe it would be correct to assume that higher-traffic websites
which are at a risk of denial of service (e.g. by folks that envy their
success) would generally be sufficiently knowledgeable to make an
explicit choice for their workload. The less experienced folks that will
rely on the defaults are probably also the folks who are most likely to
be breached and thus higher costs provide a real value-add against
hashes being cracked.
Best regards
Tim Düsterhus
I've now did the maths and you really need rate limiting no matter if you use costs 10, 11 or 12, so I believe the DoS argument is a little moot.
Yes, someone being malicious could easily generate enough requests to create an Denial of Service Attack, but I was referring to normal users logging in, on a small hosting service.
Think of a little web-shop that has just sent out an email to ~30,000 customers, and initially they get a gentle ~20 customers logins at a time... with a cost of 10, that causes the HTML for other all other pages to go from 0.09 seconds to ~1.1 seconds, not good, but manageable; cost of 11 takes that to ~2.1 seconds; cost of 12 goes to ~4.2 seconds.
(I got those numbers with a simple ab -n 200 -c 20
to call password_hash, and while true; do curl -o /dev/null -s -w '%{time_total}\n'
to request a basic page while this is running to get some rough averages).
While a high cost might make you feel good, the DoS problem is real, especially on older hardware - 10 is still fine today, 11 is a fair improvement against brute force guessing, 12 is just burning CPU cycles today, simply because the difference does not address the problem of commonly used passwords (like 123456, password1, monkey, etc).
The attacker does not know which users use less secure passwords and thus will spend effort for "secure" and "insecure" passwords alike. Doubling the costs will mean that each password takes twice as long to crack on average, making cracking twice as expensive. For less secure passwords that can make the difference between "being cracked" and "not being cracked" if the attacker is willing to spend a given amount of CPU time per password.
Yep, and we are defining a baseline, a default that is good enough for everyone; this is why I'd consider what is being achieved, think of normal customers, choosing passwords that can be found on the 14.3 million record RockYou list, to test that at "640 hashes per second", would be 6.2 hours per hash, so the 11 vs 12 cost for these people won't really make much of a difference to them.
Craig
For those who want a bit of background, while this 3 years old video covers a different subject, @chick3nman (of hashcat fame) notes the use/value of bcrypt:
On 09/22/2023 2:04 AM CDT Nicolas Grekas nicolas.grekas+php@gmail.com wrote:
I was wondering if you considered also raising the Argon2 default cost? Has
this been discussed?
Argon2 defaults are actually quite high at a theoretical speed of ~1.3 kH/s/GPU (960,000,000,000/(641024^2)/(34-1) or in general bandwidth/(m1024)/(3t-1)). The actual speeds are likely half that or less because of GPU memory size being the limiting factor. Note "<10 kH/s/GPU" is considered good.
I just opened the vote for the "Increasing the default BCrypt cost" RFC.
The RFC contains a two votes, one primary vote that requires a 2/3
majority to pass and a secondary vote deciding on the new costs with a
simple majority. Voting runs 2 weeks until 2023-10-05 17:45 UTC.Please find the following resources for your references:
Hi Tim,
Thanks for your work on this. I think bumping the default BCrypt cost from 10 to 11 is reasonable, as this typically adds less than 100 milliseconds additional latency, which shouldn't be too noticeable for users logging in.
However, I am concerned about changing the default directly from 10 to 12. Per the benchmarks in the RFC, even on recent hardware like the Apple M1 Pro this adds 179 ms additional time to verify a password (compared to 60 ms for the change to 11). This would be a noticeable slowdown for user logins.
It gets even worse on older hardware, with the example of the 2011 Core i5 adding 247 milliseconds additional time at a cost of 12, vs. 81 ms additional time using a cost of 11.
It will be easy to bump the default cost again in the future, so I think a more gradual increase will be safer to avoid an obvious degradation to user login time.
Best regards,
Theodore
Hi
Thanks for your work on this. I think bumping the default BCrypt cost from 10 to 11 is reasonable, as this typically adds less than 100 milliseconds additional latency, which shouldn't be too noticeable for users logging in.
However, I am concerned about changing the default directly from 10 to 12. Per the benchmarks in the RFC, even on recent hardware like the Apple M1 Pro this adds 179 ms additional time to verify a password (compared to 60 ms for the change to 11). This would be a noticeable slowdown for user logins.
It gets even worse on older hardware, with the example of the 2011 Core i5 adding 247 milliseconds additional time at a cost of 12, vs. 81 ms additional time using a cost of 11.
Logging in should generally be a rare thing for a given user, making a
longer delay more acceptable. All the services I interact with, except
for my bank, do not ask for a password more than twice per day with the
majority allowing for indefinite session lengths.
As per
https://www.nngroup.com/articles/response-times-3-important-limits/, any
delay above 100ms is perceptible, but as long as it's below 1000ms, it's
okay without taking any special measures.
As given in the RFC, costs of 12 stay well below 500ms for all tested
CPUs. The ARM CPUs tested by Remi are slower than the CPUs I tested, but
even those are below 430ms.
From my personal experience as a developer of a software that uses 12
since 2021, costs of 12 do not really feel slow even when logging in
multiple times in a short period to test the login process.
It will be easy to bump the default cost again in the future, so I think a more gradual increase will be safer to avoid an obvious degradation to user login time.
I'm concerned about this actually happening. Increasing the default from
10 is long overdue and is only happening, because I accidentally
stumbled over this issue. As far as I can tell there is no procedure to
perform this kind of periodic reevaluation of defaults.
Best regards
Tim Düsterhus
Please find the following resources for your references:
RFC Text: https://wiki.php.net/rfc/bcrypt_cost_2023
Discussion Thread: https://externals.io/message/121004
Feedback by a Hashcat team member on Fediverse:
https://phpc.social/@tychotithonus@infosec.exchange/111025157601179075
I did a tiny bit of my own research, and could not find any
recommendations more specific than "10 or more" as the cost factor.
Typically, the advice is "use a more modern system like argon2id".
However, I did notice some sites mention that systems ought to check
for a maximum length of 72 bytes when using bcrypt:
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#input-limits
As far as I can tell, PHP does not do this check. I am not sure if the
implementation(s) used suffer(s) from the limitation that is the
source of this recommendation. Perhaps someone has time to investigate
this? Anyway, it's "future work."
I have voted for 11, but will not be hurt in any way if 12 wins.
Yes, BCrypt uses only the first 72 bytes for hash generation. You can
test it with:
var_dump(password_verify(str_repeat('a', 72).'sdfsdf',
password_hash(str_repeat('a', 80), PASSWORD_BCRYPT)));
But I would not consider this an issue. Users rarely create passwords
longer than 72 bytes. 72 bytes is still a very long password and not
easily guessable. What's more important is to have the minimum limit
check. But why bother checking the 72 maximum if the algorithm won't
complain about longer input? It doesn't impact security in any way.
Hi
I did a tiny bit of my own research, and could not find any
recommendations more specific than "10 or more" as the cost factor.
Typically, the advice is "use a more modern system like argon2id".
Please see this email of mine regarding Argon2:
https://news-web.php.net/php.internals/120996
Other than that, the recommendation for BCrypt's cost factor (and
basically also Argon's tunables) is "as high as feasible for your use case".
See also this post on Fediverse (it's also referenced in the initial
email of the voting thread):
https://phpc.social/@tychotithonus@infosec.exchange/111025157601179075
However, I did notice some sites mention that systems ought to check
for a maximum length of 72 bytes when using bcrypt:
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#input-limitsAs far as I can tell, PHP does not do this check. I am not sure if the
implementation(s) used suffer(s) from the limitation that is the
source of this recommendation. Perhaps someone has time to investigate
this? Anyway, it's "future work."
BCrypt-as-specified has a limit of at most 72 bytes, none of which may
be NUL. Additional characters will simply be ignored. Think of it like
the password would be passed through substr($password, 0, 72)
. The
implementation used is crypt_blowfish by Openwall [1]. The limit in the
source code is given by this loop:
(BF_N (16) + 2) * 4 is 72
The behavior for longer passwords is well-defined, so I'd say that PHP
doesn't need any additional check. The only thing that could be done
differently is throwing an exception and this is likely not a good idea
for such a generic function as 'password_hash'.
I have voted for 11, but will not be hurt in any way if 12 wins.
Best regards
Tim Düsterhus
I know I'm late but bcrypt cost 12 (which looks like the winner) is high. Cost 12 is ~1 kH/s/GPU and the accepted limit for good settings is <10 kH/s/GPU. Cost 12 is 10x stronger than it needs to be as a minimum. I believe cost 10 is a good default for the next 1-3 years and cost 11 should be good for the next 5-10 years.
There are two methods for picking settings: defender takes ≲100 ms and attacker gets <10 kH/s/GPU. Costs 9, 10, and 11 are the only ones that meet both limits (cost 11 for some defenders).
Also the poll for increasing from cost 11 to cost 12 should be a 2/3 majority to get cost 12. Since the poll for increasing from cost 10 to cost 11 is a 2/3 majority. You can think of this as a 2/3 majority poll to increase to cost 11 followed by a 2/3 majority poll to increase to cost 12.
On 09/21/2023 12:26 PM CDT Tim Düsterhus tim@bastelstu.be wrote:
Hi
I just opened the vote for the "Increasing the default BCrypt cost" RFC.
The RFC contains a two votes, one primary vote that requires a 2/3
majority to pass and a secondary vote deciding on the new costs with a
simple majority. Voting runs 2 weeks until 2023-10-05 17:45 UTC.Please find the following resources for your references:
RFC Text: https://wiki.php.net/rfc/bcrypt_cost_2023
Discussion Thread: https://externals.io/message/121004
Feedback by a Hashcat team member on Fediverse:
https://phpc.social/@tychotithonus@infosec.exchange/111025157601179075Best regards
Tim Düsterhus--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi
Let me link your Fediverse reply for reference as well:
https://infosec.exchange/@sc00bz/111178818937154254
I know I'm late but bcrypt cost 12 (which looks like the winner) is high. Cost 12 is ~1 kH/s/GPU and the accepted limit for good settings is <10 kH/s/GPU. Cost 12 is 10x stronger than it needs to be as a minimum. I believe cost 10 is a good default for the next 1-3 years and cost 11 should be good for the next 5-10 years.
Yes, you were late (the vote was not yet closed at the time of your
Fediverse post / your email, though).
According to your Fediverse reply beginning with next year, 11 would be
an appropriate value for longevity. The default will only change
starting in PHP 8.4 which is roughly 13 months away from its gold
release. It will likely even longer before it actually broadly hits the
users.
The next Debian Stable is expected to be released in the middle of 2025,
with freeze starting around the end of 2024. Depending on the timing and
compatibility of PHP 8.4, it might or might not make the cut. In any
case, Debian will see PHP 8.4 no earlier than middle of 2025 and then
users will need to upgrade to that version.
Likewise the next Ubuntu LTS is expected in April 2024 and thus will not
include PHP 8.4, the first LTS version to include PHP 8.4 will arrive in
April 2026.
I also expect that those versions will live in production way past the
date the PHP project itself stops supporting them. Erring on the side of
"strong" seems to be the right choice to me, especially since a CPU that
is 12 years old as of today handles a cost of 12 in less than 330ms
(which still is acceptable for interactive authentication), with current
server CPUs (Xeon Gold 5416S mentioned by Alexandru) being at around the
100ms you mentioned.
Also the poll for increasing from cost 11 to cost 12 should be a 2/3 majority to get cost 12. Since the poll for increasing from cost 10 to cost 11 is a 2/3 majority. You can think of this as a 2/3 majority poll to increase to cost 11 followed by a 2/3 majority poll to increase to cost 12.
I've included the majority rules within the first version of the RFC, so
it was clear to everyone who voted how the results are going to be
interpreted. Redefining the majority rules shortly before the end of the
vote would be questionable, that's why I proceeded to announce the
results with the rules that were announced at the start of the vote.
I also don't think that 12 is a wrong choice for the reasons outlined above.
Best regards
Tim Dsüterhus
Also the poll for increasing from cost 11 to cost 12 should be a 2/3
majority to get cost 12. Since the poll for increasing from cost 10 to cost
11 is a 2/3 majority. You can think of this as a 2/3 majority poll to
increase to cost 11 followed by a 2/3 majority poll to increase to cost 12.
That's not how voting works in the PHP project. The 2/3 is for whether or
not the feature change should be made at all. In the case that there are
multiple implementations or variations, the choice between those is usually
simple majority. People can and do vote no on the main 2/3 vote if they
feel that only one of the implementations/variations are acceptable.
Jordan
That's not how voting works in the PHP project. The 2/3 is for whether or not the feature change should be made at all. In the case that there are multiple implementations or variations, the choice between those is usually simple majority. People can and do vote no on the main 2/3 vote if they feel that only one of the implementations/variations are acceptable.
Isn't it odd, if I had a vote, I'd have changed my first one to no if it meant jumping the default from 10 to 12 (ref shared hosting, and low powered servers)... doesn't matter though, when I finally get around to updating WordPress to use password_hash()
, I'll probably set the cost rather than using the default (weird how that happens, some people think they are making things more secure, but end up making things worse).
Craig
Hi
I just opened the vote for the "Increasing the default BCrypt cost" RFC.
The RFC contains a two votes, one primary vote that requires a 2/3
majority to pass and a secondary vote deciding on the new costs with a
simple majority. Voting runs 2 weeks until 2023-10-05 17:45 UTC.Please find the following resources for your references:
The RFC was unanimously accepted with 25 votes. The secondary vote
decided on a new cost of 12 (14 votes, 53.8%).
The PR for the implementation is here:
https://github.com/php/php-src/pull/12367
Best regards
Tim Düsterhus