1

I have two questions here:

1) How many possible randomly generated salts could be generated using PHP's password_hash() function?

2) According to php.net it states that the return value is a contains "the algorithm used, the cost and salt are returned as part of the hash" and I assume the hash itself. So from my understanding in a returned string of $2y$10$x27FUiXA/hFKjD7NDxyD6e63ac4gmCkTqXRpmy1Rk.MxXAqRd8yO6 the 2y indicates the algorithm, the 10 indicates the cost, but which characters indicate the salt and which characters indicate the hash?

  • Since the length of the password will return a different value you will have to factor that in. According to the PHP docs a password with the length of 8 is 96^8 = 7,21389578984e+15. This number alone for one length is pretty astronomical. So if combination possibilities is a concern you should be able to put that to rest. – Bacon Brad Apr 1 '16 at 22:38
  • @BradMetcalf Can you point to the place in the docs it mentions this? Your value is very different from the one in the answer below. – kojow7 Apr 1 '16 at 22:56
  • 1
    @kojow7 I believe brad is misunderstanding your question. You were specifically asking about the salts which are 128 bit with bcrypt (the current default mode for password_hash()) which means that there are 2^128 possible salts. Additionally, this is a hashing function therefore the length shouldn't ever change. I believe brad was thinking you were asking about total number of possible passwords with length n or something similar. – d0nut Apr 2 '16 at 1:31
3

1) The salt for password_hash() is a 128 bit salt which is the first 22 base64 characters after the cost factor. In your example, the salt would be x27FUiXA/hFKjD7NDxyD6e. Because it is 128 bit, you can calculate the number of potential salts as 2^128 which is 3.4028237e+38. So, in short, a lot.

2) Well this didn't seem like a question so i'll try to answer the "which characters indicate the hash" part. The hash are the remaining 31 characters after the salt. In your case 63ac4gmCkTqXRpmy1Rk.MxXAqRd8yO6.

(also, your understanding is correct. 2y is the algorithm, and 10 is the cost.)


It is important to note that password_hash() can change its implementation to use a different algorithm if you update PHP to a newer version that changes it.

PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5.0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP.

If you use PASSWORD_BCRYPT it will always use bcrypt.

  • To add to this, there's an effort to add Argon2i v1.3 to password_hash() as an option in 7.1 and possibly as the default in 7.3/8.0 :) – Scott Arciszewski Apr 8 '16 at 16:00
  • @ScottArciszewski Thanks for the additional information, scott. What are your thoughts on using argon in production systems? My understanding is that it has only been "in the wild" for about 3 years and I'm still a little nervous about using it since it's only been out for a relatively short period of time. – d0nut Apr 8 '16 at 16:21
  • PHP 7.1 will probably come out later this year. Presumably 7.3 will come out at the end of 2018. The primitives that Argon2i is based on are pretty well-studied, so I don't anticipate any significant advances there. The weaknesses, if any, are going to be in the form of "You can optimize your brute force attempts by doing this strategy" e.g. trading 32x memory for a 2x speedup. – Scott Arciszewski Apr 9 '16 at 19:14
  • @Scott should I assume, for all intents and purposes, that argon is safe to use, then? – d0nut Apr 9 '16 at 21:35
  • I would consider Argon2i v1.3 safe to use, but I understand that many do not feel comfortable switching to it just yet. Bcrypt truncates after 72 characters or a single NUL byte. Scrypt has weird corner cases. PBKDF2 is the weakest of the four. Yescrypt / Argon2i are the two I'd trust, personally. Bcrypt(Base64Encode(SHA384($password))) is a great stop-gap for today. This blog post will be where I keep up-to-date recommendations. – Scott Arciszewski Apr 10 '16 at 1:51

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.