Jukka Zitting created OAK-634:
---------------------------------
Summary: PasswordUtility.isSame() performance bottleneck
Key: OAK-634
URL: https://issues.apache.org/jira/browse/OAK-634
Project: Jackrabbit Oak
Issue Type: Bug
Components: core
Reporter: Jukka Zitting
The default 1000 SHA-256 iterations used for password hashes are seriously
impacting the performance of login() calls. Here's a performance report of the
number of milliseconds that a successful login takes with Jackrabbit 2.x and
Oak (with an in-memory MK):
{noformat}
# Login min 10% 50% 90% max
Jackrabbit 560 570 577 704 1522
Oak-Memory 2537 2586 2630 2811 2916
{noformat}
Over 50% of that time is spent doing hash iterations in
{{PasswordUtility.isSame()}}. This is a problem for two main reasons:
# It severely drags down performance of acquiring a new session; something
which should be essentially free.
# It opens the denial of service attack vector of just bombarding a system with
login attempts, which would cause CPU usage to spike.
Iterating a password hash is a good idea for preventing offline attacks against
a stolen password database (though instead of SHA-256 we should be using
something like bcrypt that's explicitly designed and analyzed for this
purpose), but the current implementation doesn't make much sense in a scenario
like ours where we can expect dozens or hundreds of logins per second even in
normal non-peak use cases. Password iteration makes more sense in use cases
where logins are infrequent (e.g. once a day per user) and persisted through
something like a session key.
So, assuming we want to keep the cost of an offline attack high, here's what I
suggest we do for password-based logins:
* Switch to bcrypt or a similar password hashing algorithm if possible.
* For each active user in the system, keep an in-memory record to speed up
login calls.
** On a successful login the record should be updated to contain a password
hash with just one iteration (calculated from the plain text password provided
in the successful login). Use this instead of the in-repository password hash
for authenticating further login attempts.
** The record should also keep track of unsuccessful login attempts and limit
them to at most N attempts per minute to prevent DOS attacks.
The result of such in-memory record keeping should be to massively speed up
normal logins (point 1 above) and also to cap the CPU use of the potential DOS
attack (point 2) to O(N*K) cycles per minute, with K being the total number of
users in the system.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira