Hi
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've
created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.
https://wiki.php.net/rfc/bcrypt_cost_2023
This message is intended to officially open the discussion period for
that RFC.
Best regards
Tim Düsterhus
Hi Tim
Hi
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.
These are the kind of things that are easily forgotten.
Thank you for taking care of this!
I just noticed one small detail.
From the RFC text: "All tests were carried out using wall-power." I guess you mean wall-time?
This message is intended to officially open the discussion period for that RFC.
Best regards
Tim Düsterhus
Kind regards
Niels
Hi
I just noticed one small detail.
From the RFC text: "All tests were carried out using wall-power." I guess you mean wall-time?
No, this means that the laptops whose CPUs where tested were plugged
into the wall :-)
I've added a parenthesis clarifying what that intends to mean.
Best regards
Tim Düsterhus
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.
Thanks Tim,
Just quickly running this on two AWS EC2 servers, to give rough figures for a VM (note usual issues like noisy neighbours, turbo-boost, thermal throttling, etc).
t2.nano
Cost 8: 2.083060 total (0.020831 per hash)
Cost 9: 4.115596 total (0.041156 per hash)
Cost 10: 8.238419 total (0.082384 per hash)
Cost 11: 16.334089 total (0.163341 per hash)
Cost 12: 32.693785 total (0.326938 per hash)
Cost 13: 65.587982 total (0.655880 per hash)
Cost 14: 131.358058 total (1.313581 per hash)
t2.small
Cost 8: 2.062625 total (0.020626 per hash)
Cost 9: 4.142067 total (0.041421 per hash)
Cost 10: 8.231646 total (0.082316 per hash)
Cost 11: 16.851889 total (0.168519 per hash)
Cost 12: 32.814440 total (0.328144 per hash)
Cost 13: 69.409889 total (0.694099 per hash)
Cost 14: 133.682196 total (1.336822 per hash)
Both nano and small only have 1 vCPU, have 0.5 vs 1 GiB RAM, and a different number of CPU Credits/hr.
We recently discussed hashing and costs at one of our OWASP meetings, we came to conclusion that the default of 10 for bcrypt probably should be increased, but only to 11 for typical websites. The main concern was about making denial-of-service attacks easier (think of a normal website developer, who won't limit the number of login attempts).
It's also worth keeping in mind the difference between online vs offline attacks, what it's being used for, human behaviour when it comes to choosing bad passwords ("123456" and "Password1!" will still be guessed very quickly), etc.
Craig
@Craig warning, it's very random what kind of CPU performance you get
on your t2 instances, the CPUs vary greatly from modern to many years
old.
I know of Fortune 500 companies that have automated systems to spin up
t2 instances until they randomly get "a good one", then discard the
others, because the cpu performance vary so widely
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.Thanks Tim,
Just quickly running this on two AWS EC2 servers, to give rough figures for a VM (note usual issues like noisy neighbours, turbo-boost, thermal throttling, etc).
t2.nano
Cost 8: 2.083060 total (0.020831 per hash)
Cost 9: 4.115596 total (0.041156 per hash)
Cost 10: 8.238419 total (0.082384 per hash)
Cost 11: 16.334089 total (0.163341 per hash)
Cost 12: 32.693785 total (0.326938 per hash)
Cost 13: 65.587982 total (0.655880 per hash)
Cost 14: 131.358058 total (1.313581 per hash)t2.small
Cost 8: 2.062625 total (0.020626 per hash)
Cost 9: 4.142067 total (0.041421 per hash)
Cost 10: 8.231646 total (0.082316 per hash)
Cost 11: 16.851889 total (0.168519 per hash)
Cost 12: 32.814440 total (0.328144 per hash)
Cost 13: 69.409889 total (0.694099 per hash)
Cost 14: 133.682196 total (1.336822 per hash)Both nano and small only have 1 vCPU, have 0.5 vs 1 GiB RAM, and a different number of CPU Credits/hr.
We recently discussed hashing and costs at one of our OWASP meetings, we came to conclusion that the default of 10 for bcrypt probably should be increased, but only to 11 for typical websites. The main concern was about making denial-of-service attacks easier (think of a normal website developer, who won't limit the number of login attempts).
It's also worth keeping in mind the difference between online vs offline attacks, what it's being used for, human behaviour when it comes to choosing bad passwords ("123456" and "Password1!" will still be guessed very quickly), etc.
Craig
To unsubscribe, visit: https://www.php.net/unsub.php
On 09/07/2023 4:37 PM CDT Craig Francis craig@craigfrancis.co.uk wrote:
We recently discussed hashing and costs at one of our OWASP meetings, we came to conclusion that the default of 10 for bcrypt probably should be increased, but only to 11 for typical websites. The main concern was about making denial-of-service attacks easier (think of a normal website developer, who won't limit the number of login attempts).
I fought long and hard to get bcrypt down from cost 12 to only cost 10 even though cost 9 was over powered vs the other settings. At the time cost "8.1" was equivalent to the other settings. After the recent settings increase of the others, cost "8.7" is equivalent. Currently all of the OWASP settings come directly from me except bcrypt. The only way I was able to get it down to cost 10 was giving equivalent settings to cost 12 for the other algorithms. Just to show that those numbers were obviously too high. Note that bcrypt cost 12 is currently as strong as PBKDF2-HMAC-SHA256 with ~6,000,000 iterations. Which is an insane number for web auth.
Anyway I don't look forward to arguing with OWASP to keep bcrypt at cost 10. Even though it's currently 2.5x stronger than the other accepted settings.
Hi
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've
created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.
I think 12 looks reasonable.
I've performed some tests myself on private hosted servers with
newer hardware with good results for 12 around 0.1 seconds.
Can this be integrated into PHP 8.3, as it's not a new feature that can
cause problems?
Pushing it to 8.4 will delay the real usage with 2-3 more years already.
I feel like the hardware performance improvements (specifically single
thread performance) slightly increased in the past 3-4 years, and soon most
of the hosting providers will be using it.
Thank you for looking into this. Having good security configuration by
default is important.
Regards,
Alex
Hi
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've
created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.I think 12 looks reasonable.
I've performed some tests myself on private hosted servers with
newer hardware with good results for 12 around 0.1 seconds.
wow, that is a 33% reduction even compared to the Xeon E-2246G and thus
hard to believe. What CPU is that?
Can this be integrated into PHP 8.3, as it's not a new feature that can
cause problems?
The release managers for PHP 8.3 would need to decide that. However I'd
rather not include this in PHP 8.3 at this point.
Pushing it to 8.4 will delay the real usage with 2-3 more years already.
IMO this is fine. Common frameworks can and do already use a different
default. Symfony apparently is at 13 by default. Laravel uses 10, but
I've already pinged someone on Mastodon to maybe have a look at the
results of this RFC:
https://phpc.social/@timwolla/111025125667858110
The current default of 10 is not insecure and rolling this out a little
more slowly will mean that more and more of the old and slow hardware
will be retired and replaced by modern hardware, lessening the impact.
I feel like the hardware performance improvements (specifically single
thread performance) slightly increased in the past 3-4 years, and soon most
of the hosting providers will be using it.
From my experience as a developer of a software that is commonly run on
shared hosting, web hosters love their ancient hardware, because it's
fully depreciated from a taxation / accounting PoV and every extra day
it is used is "free money". Customers commonly are not able to tell they
are running with tens of other customers on this ancient hardware and
thus won't complain ("loading times of 1 second are fine").
Best regards
Tim Düsterhus
web hosters love their ancient hardware
No kidding. dreamhost.com host over 1.5 million websites, presumably most
are on their "Shared Unlimited" package, which runs on
AMD Opteron 4122, a high-end server CPU from 2010.
Some benchmarks there:
hanshenrik@jonathan-dayton:~$ cat /proc/cpuinfo | head
processor : 0
vendor_id : AuthenticAMD
cpu family : 16
model : 8
model name : AMD Opteron(tm) Processor 4122
stepping : 0
microcode : 0x10000da
cpu MHz : 2200.000
cache size : 512 KB
physical id : 0
hanshenrik@jonathan-dayton:~$ php -v
PHP 8.2.5 (cli) (built: Apr 13 2023 18:45:57) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.5, Copyright (c) Zend Technologies
with Zend OPcache v8.2.5, Copyright (c), by Zend Technologies
hanshenrik@jonathan-dayton:~$ hyperfine 'php -r
'''password_hash("password1234",PASSWORD_BCRYPT,["cost"=>9]);''''
Benchmark 1: php -r
'password_hash("password1234",PASSWORD_BCRYPT,["cost"=>9]);'
Time (mean ± σ): 122.7 ms ± 2.4 ms [User: 78.1 ms, System: 33.7
ms]
Range (min … max): 120.0 ms … 127.5 ms 22 runs
hanshenrik@jonathan-dayton:~$ hyperfine 'php -r
'''password_hash("password1234",PASSWORD_BCRYPT,["cost"=>10]);''''
Benchmark 1: php -r
'password_hash("password1234",PASSWORD_BCRYPT,["cost"=>10]);'
Time (mean ± σ): 166.4 ms ± 2.7 ms [User: 115.1 ms, System: 39.3
ms]
Range (min … max): 163.0 ms … 171.2 ms 18 runs
hanshenrik@jonathan-dayton:~$ hyperfine 'php -r
'''password_hash("password1234",PASSWORD_BCRYPT,["cost"=>11]);''''
Benchmark 1: php -r
'password_hash("password1234",PASSWORD_BCRYPT,["cost"=>11]);'
Time (mean ± σ): 246.0 ms ± 5.2 ms [User: 198.2 ms, System: 34.5
ms]
Range (min … max): 241.0 ms … 256.5 ms 12 runs
hanshenrik@jonathan-dayton:~$ hyperfine 'php -r
'''password_hash("password1234",PASSWORD_BCRYPT,["cost"=>12]);''''
Benchmark 1: php -r
'password_hash("password1234",PASSWORD_BCRYPT,["cost"=>12]);'
Time (mean ± σ): 409.7 ms ± 3.6 ms [User: 355.6 ms, System: 41.6
ms]
Range (min … max): 405.3 ms … 416.6 ms 10 runs
hanshenrik@jonathan-dayton:~$ hyperfine 'php -r
'''password_hash("password1234",PASSWORD_BCRYPT,["cost"=>13]);''''
Benchmark 1: php -r
'password_hash("password1234",PASSWORD_BCRYPT,["cost"=>13]);'
Time (mean ± σ): 729.3 ms ± 10.6 ms [User: 672.5 ms, System: 43.8
ms]
Range (min … max): 717.3 ms … 754.5 ms 10 runs
must say, surprisingly good performance for a 2010 cpu
Hi
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've
created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.I think 12 looks reasonable.
I've performed some tests myself on private hosted servers with
newer hardware with good results for 12 around 0.1 seconds.wow, that is a 33% reduction even compared to the Xeon E-2246G and thus
hard to believe. What CPU is that?Can this be integrated into PHP 8.3, as it's not a new feature that can
cause problems?The release managers for PHP 8.3 would need to decide that. However I'd
rather not include this in PHP 8.3 at this point.Pushing it to 8.4 will delay the real usage with 2-3 more years already.
IMO this is fine. Common frameworks can and do already use a different
default. Symfony apparently is at 13 by default. Laravel uses 10, but
I've already pinged someone on Mastodon to maybe have a look at the
results of this RFC:https://phpc.social/@timwolla/111025125667858110
The current default of 10 is not insecure and rolling this out a little
more slowly will mean that more and more of the old and slow hardware
will be retired and replaced by modern hardware, lessening the impact.I feel like the hardware performance improvements (specifically single
thread performance) slightly increased in the past 3-4 years, and soon
most
of the hosting providers will be using it.From my experience as a developer of a software that is commonly run on
shared hosting, web hosters love their ancient hardware, because it's
fully depreciated from a taxation / accounting PoV and every extra day
it is used is "free money". Customers commonly are not able to tell they
are running with tens of other customers on this ancient hardware and
thus won't complain ("loading times of 1 second are fine").Best regards
Tim Düsterhus--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi
web hosters love their ancient hardware
No kidding. dreamhost.com host over 1.5 million websites, presumably most
are on their "Shared Unlimited" package, which runs on
AMD Opteron 4122, a high-end server CPU from 2010.
Some benchmarks there:
It appears your benchmarks are broken, because you're also measuring the
startup cost of PHP itself. You should see an approximate doubling in
time taken for each increase of the cost, but you have 122ms for 9 and
166ms for 10.
A simple microtime(true) benchmark loop as used with my test script
should be fine for ballpark estimates, as password_hash()
is pretty
heavy, dwarfing the measurement overhead.
Best regards
Tim Düsterhus
you're also measuring the startup cost of PHP itself.
yup correct
A simple microtime(true) benchmark loop as used with my test script should be fine for ballpark estimates
agreed
dwarfing the measurement overhead.
wouldn't count out random cpu context switch/background noise
completely, see my hyperfine benchmark for cost 13:
Range (min … max): 717.3 ms … 754.5 ms 10 runs
- over 10 runs, the fastest was 717ms and the slowest was 754ms, so
background noise made at least 37ms difference there.. but yeah
anyway, here's from your script:
hanshenrik@jonathan-dayton:~$ time php bench.php
Cost 8: 2.022854 total (0.020229 per hash)
Cost 9: 4.176210 total (0.041762 per hash)
Cost 10: 8.121596 total (0.081216 per hash)
Cost 11: 16.919405 total (0.169194 per hash)
Cost 12: 33.059071 total (0.330591 per hash)
Cost 13: 66.761731 total (0.667617 per hash)
Cost 14: 140.695820 total (1.406958 per hash)
real 4m31.854s
user 4m13.115s
sys 0m2.168s
hanshenrik@jonathan-dayton:~$ cat /proc/cpuinfo | head
(...)
model name : AMD Opteron(tm) Processor 4122
Hi
web hosters love their ancient hardware
No kidding. dreamhost.com host over 1.5 million websites, presumably most
are on their "Shared Unlimited" package, which runs on
AMD Opteron 4122, a high-end server CPU from 2010.
Some benchmarks there:It appears your benchmarks are broken, because you're also measuring the
startup cost of PHP itself. You should see an approximate doubling in
time taken for each increase of the cost, but you have 122ms for 9 and
166ms for 10.A simple microtime(true) benchmark loop as used with my test script
should be fine for ballpark estimates, aspassword_hash()
is pretty
heavy, dwarfing the measurement overhead.Best regards
Tim Düsterhus
Hi
I think 12 looks reasonable.
I've performed some tests myself on private hosted servers with
newer hardware with good results for 12 around 0.1 seconds.wow, that is a 33% reduction even compared to the Xeon E-2246G and thus
hard to believe. What CPU is that?
That was a new Xeon Gold 5416S.
I got lucky being able to run some tests on it before being pushed to
production replacing a slightly older one, a Xeon Gold 5218.
I'll be able to test that as well, but I feel like anyway the hardware I
used is not what is usually in general.
Actually, it is even less relevant, as it is meant to be used by a high
performing MySQL server and not for running PHP.
Pushing it to 8.4 will delay the real usage with 2-3 more years already.
IMO this is fine. Common frameworks can and do already use a different
default. Symfony apparently is at 13 by default. Laravel uses 10, but
I've already pinged someone on Mastodon to maybe have a look at the
results of this RFC:https://phpc.social/@timwolla/111025125667858110
The current default of 10 is not insecure and rolling this out a little
more slowly will mean that more and more of the old and slow hardware
will be retired and replaced by modern hardware, lessening the impact.
Understood, yes, I agree.
I feel like the hardware performance improvements (specifically single
thread performance) slightly increased in the past 3-4 years, and soon
most
of the hosting providers will be using it.From my experience as a developer of a software that is commonly run on
shared hosting, web hosters love their ancient hardware, because it's
fully depreciated from a taxation / accounting PoV and every extra day
it is used is "free money". Customers commonly are not able to tell they
are running with tens of other customers on this ancient hardware and
thus won't complain ("loading times of 1 second are fine").
Yes, I think I evaluated the hardware upgrade lifecycle to be around 5
years, but in reality it's 10-15 years.
And also the CPU options used by hosting providers are cost oriented, to
get the most performance per dollar.
Thank you,
Alex
Hi
in response to the recent "PASSWORD_DEFAULT value" thread [1], I've
created an RFC to discuss an increase of the default BCrypt costs for
password_hash()
from the current value of 10.https://wiki.php.net/rfc/bcrypt_cost_2023
This message is intended to officially open the discussion period for
that RFC.
The minimum 14 days of discussion will be over tomorrow. I believe the
RFC is clearly written, sufficiently explains possible drawbacks and
gives enough data to make an information decision.
As such I don't expect any more meaningful discussion and plan open the
vote shortly after the 14 days are actually over to get this off my list.
Best regards
Tim Düsterhus