Contact support

We reply by e-mail, usually within two days.

Google reCAPTCHA checks this submission against abuse; data is sent to Google. The script loads only once you open this form.

← All posts

What a password costs on a Raspberry Pi

Statistics pages here can be protected with a password. Hashing that password is the one operation in this service that is supposed to be slow — that is what makes a stolen hash expensive to attack. The question is how slow, on this hardware.

Measured on the machine that runs this site, PHP 8.4.21 on aarch64:

PASSWORD_DEFAULT560 ms(resolves to cost 12)
cost 12595 ms
cost 11277 ms
cost 10138 ms

bcrypt's cost parameter is an exponent: each step doubles the work. The measurements show exactly that doubling, which is a good sign that nothing else is interfering.

Why the default is the wrong choice here

PHP raised bcrypt's default cost from 10 to 12. On a desktop server that is a sensible upgrade — it is a few tens of milliseconds. On a small ARM board it is over half a second of pure CPU, on a machine that is also drawing counter images for everyone else at the same time.

Half a second per login is bad on its own. It is worse as an invitation: anyone can call the login endpoint, and each call spends 560 ms of the one CPU that serves the whole site. That turns password verification into the cheapest denial-of-service surface available.

So the cost is pinned to 10 rather than left to the default. That is deliberately weaker than what PHP now picks, and it should be said plainly rather than buried: a cost-10 hash is four times cheaper to attack than a cost-12 hash. What buys that back is what the password actually protects — the visibility of a page of visit counts, not an account, not money, not identity. There is nothing behind it to take over.

The part that is easy to miss

PASSWORD_DEFAULT is a moving value by design. Code written years ago that uses it will silently get slower with each PHP upgrade — the same source, the same input, several times the runtime. That is the intended behaviour, and it is right for most software.

It is only wrong when the machine cannot absorb it, and nothing warns you when it cannot. The upgrade succeeds, the tests pass, the page still works. It just takes half a second longer, and nobody looks at that number unless they go and measure it.

Advertisement