-->

Argon2i in PHP7 - Picking Appropriate Options

2019-05-11 17:21发布

问题:

What values should I use for generating Argon2i hashes and how can I find the appropriate settings my hardware can afford?

Namely:

memory_cost
time_cost
threads

as:

$options = [
    'memory_cost' => 1<<17,
    'time_cost'   => 4,
    'threads'     => 3,
];

$hash = password_hash('test', PASSWORD_ARGON2I, $options);

There is a simple script in PHP docs for finding the appropriate cost value for bcrypt hashes. How can this be fitted for Argon2?

回答1:

From: PHP RFC Argon2 password_hash

Cost Factors

From:

Due to the variety of platforms PHP runs on, the cost factors are deliberately set low as to not accidentally exhaust system resources on shared or low resource systems when using the default cost parameters. Consequently, users should adjust the cost factors to match the system they're working on. The following list outlines hashing performance on various systems using these default cost values.

Common Cloud Server 512 MB, 1 Core: 3-5 ms
Common Cloud Server 2 GB, 2 Core, 1-3 ms
512 MB Raspberry Pi Zero: 75-85ms

As Argon2 doesn't have any “bad” values, however consuming more resources is considered better than consuming less. Users are encouraged to adjust the cost factors for the platform they're developing for.

Threads

From: What Is The Recommended Number Of Iterations For Argon2

The argon2 paper gives the following procedure (paraphrased) for determining the parameters you should use:

    1. Figure out how many threads you can use, choose $h$ accordingly.
    1. Figure out how much memory you can use, choose $m$ accordingly.
    1. Decide on the maximum time $x$ you can spend on it, choose the largest $t$ such that it takes less than $x$ with your system and other parameter choices.

I.e. they recommend you run it on your system and decide the largest parameters that match your limits on memory and processor time use.

From The Argon 2 spec.

(link here)

  • Degree of parallelism p determines how many independent (but synchronizing) computational chains can be run. It may take any integer value from 1 to 2^24 -1

  • Memory size m can be any integer number of kilobytes from 8p to 2^32 −1. The actual number of blocks is m′, which is m rounded down to the nearest multiple of 4p.

  • Number of iterations t (used to tune the running time independently of the memory size) can be any integer number from 1 to 2^32 -1

Further Literature

From Here

  • Figure out how many threads can be used on each call to Argon2 (parallelism). They recommend twice as many as the number of cores dedicated to hashing passwords.

  • Figure out how long each call can take. One recommendation for concurent user logins is to keep it under 0.5ms.

  • Measure the time for hashing using your chosen parameters. Find a time_cost that is within your accounted time. If time_cost=1 takes too long, lower memory_cost.

Conclusion:

So from the above extracts it seems that you want to aim for a timespan of 0.5ms as measured by PHP microtime just like in the BCrypt example. Then you can set the number of threads as being twice the number of cores your CPU is running, so say 8 for a 4core processor.

You should then be able to run a series of tests with these above two values to find a valid third value for memory_cost.

Run some tests on your server to see what the server can comfortably manage. Explore if this CLI can help.

Change the three variables in the order set out in the quote above (under Threads), so adjust memory over using large iteration counts.

In short we can't give you a "best advice" guide because it depends on what spec. you're intending to run this on...