We're using argon2-jvm to use Argon2id on our Java TCP Server.

Because its argon2id instance is thread-safe, we plan to only create a single instance for the lifetime of our app and have each request handler call it whenever necessary (e.g. for new registrations and user log-ins).

We've fine-tuned our single argon2id instance so hashing and verifying passwords both take roughly 1 second on a single thread using the approach from this answer:

  1. Use the max number of threads we can use (no. of CPUs x 2 in our case).
  2. Use the max amount of memory we can use.
  3. Tweak the number of iterations so it does not exceed our target max time (1 second in our case).

However, when the number of threads (TCP requests) accessing our argon2id instance increases (e.g. there are multiple users registering and logging in), its execution time increases as well.

Our plan now is to reconfigure our argon2id instance such that it still takes roughly 1 second to hash and verify passwords, but instead of doing so on just 1 thread, we'll be doing it on our expected max number of concurrent registrations and log-ins at any given time (e.g. 500 TCP requests).

Our concern is that, if we do so, then our hashes might not be secure enough because each request won't be getting as much processing as it should (e.g. a hash that takes about 1 second on max capacity might take only 0.25 seconds when it's the only request being made).

We feel that configuring Argon2id for max capacity is going to undershoot a secure configuration for each individual request. Is this how it's supposed to be done? Or should we stick with our configuration that takes 1 second on single threads but takes longer on multiple ones (we fear this might take too long for too many requests)?

UPDATE: I also asked the Crypto subreddit for their thoughts here.


There is no perfect solution. There is always a trade off between security, price and user experience. If you want to get both higher security and acceptable response times, consider using more hardware resources (higher price).

First estimate the risks to decide what security level you actually need. What are exactly the threats? What benefits can an attacker get in case of successful brute-forcing of single password? What will it costs for the attacker to brute-force a single password? Are the possible benefits and the costs commensurate? Does it make sense for the hacker at all? What can be costs to you and to your users to provide particular level of security? E.g. if you reduce the number of requests per server/container from 500 to 100 (to enable more hashing iterations) and increase the number of servers/containers x5, will be the price x5 acceptable to you?

Also we should distinguish two basic use cases.

  • There is a single user. For instance, a user on a laptop uses hash (derivated password) as a master password in password manager, or to encrypt/decrypt a drive. Then it makes sense for a single hash to use as much resources as possible.
  • There are multiple simultaneous requests, for instance in some web application. If some requests require too much resources, other requests (normal requests that don't use password) will notice degraded performance.

The number of threads: The main purpose of this parameter is to load memory bus as much as possible. But normal CPUs have only 2 memory channels, where as many graphic cards have 6 or 8. Thus, exhausting your server you don't exhaust the resources of the attacker. Means, it does not necessarily increases your security. That's why I'd suggest to use 1 thread.

Memory: Your application is probably performing a lot of other logic besides hashing, like evaluating permissions, calculating some business logic, searching data for particular complex criteria, creating reports, etc. How much memory need such requests? How much memory can hashing use so that the performance of the main functionality remains acceptable? May be after analysis you will conclude that you can use for hashing not more than 5% of the available memory. Just model and calculate.

The number of iterations: Then tune up the number of iterations to get the acceptable response time.

Then check your assumptions on the real environment with real users. If you see that performance is not sufficient, you can still tune them. After password validation against the old hash succeeded, you can rehash the password with new (optimized) parameters and save to database.

  • This clarified everything! So we do have the option to use a separate machine just for hashing if the need is justified, and if not, then we need to allocate a portion of the server's resources for hashing but not as much as we can jam in there because it does other things too. – Floating Sunfish Apr 10 '20 at 22:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.