Lo que cuesta una contraseña en una Raspberry Pi
Las páginas de estadísticas se pueden proteger aquí con contraseña. Calcular el hash de esa contraseña es la única operación de este servicio que debe ser lenta — eso es lo que encarece atacar un hash robado. La pregunta es cuánto, en este hardware.
Medido en la máquina que sirve esta página, PHP 8.4.21 sobre aarch64:
PASSWORD_DEFAULT | 560 ms | (resuelve a cost 12) |
| cost 12 | 595 ms | |
| cost 11 | 277 ms | |
| cost 10 | 138 ms |
El parámetro de coste de bcrypt es un exponente: cada paso duplica el trabajo. Las mediciones muestran exactamente esa duplicación, lo cual es buena señal de que no interfiere nada más.
Por qué el valor por defecto es aquí la elección equivocada
PHP subió el coste por defecto de bcrypt de 10 a 12. En un servidor de centro de datos es una subida razonable — unas pocas decenas de milisegundos. En una placa ARM pequeña son más de medio segundo de CPU pura, en una máquina que al mismo tiempo está dibujando imágenes de contador para todos los demás.
Medio segundo por inicio de sesión ya es malo de por sí. Es peor como invitación: el punto de acceso lo puede llamar cualquiera, y cada llamada consume 560 ms del único procesador que atiende toda la página. Eso convierte la verificación de contraseña en la forma más barata de saturación que existe aquí.
Por eso el coste está fijado en 10 y no dejado al valor por defecto. Es deliberadamente más débil que lo que PHP elige hoy, y conviene decirlo claro en vez de enterrarlo: un hash de coste 10 es cuatro veces más barato de atacar que uno de coste 12. Lo que lo compensa es lo que la contraseña protege realmente — la visibilidad de una página con cifras de visitas, no una cuenta, no dinero, no una identidad. Detrás no hay nada que apropiarse.
La parte que es fácil pasar por alto
PASSWORD_DEFAULT es, por diseño, un valor móvil. El código escrito hace años que lo usa se irá volviendo más lento en silencio con cada actualización de PHP — el mismo código, la misma entrada, varias veces el tiempo de ejecución. Es el comportamiento previsto, y para la mayoría del software es lo correcto.
Solo es incorrecto cuando la máquina no puede absorberlo, y nada avisa cuando no puede. La actualización funciona, las pruebas pasan, la página sigue funcionando. Simplemente tarda medio segundo más, y nadie mira ese número si no va y lo mide.