Comments on: Do Not Use sha256crypt / sha512crypt - They're Dangerous Linux. GNU. Freedom. Wed, 13 Jun 2018 20:15:45 +0000 hourly 1 By: Poul-Henning Kamp Mon, 28 May 2018 07:16:20 +0000 A few factual corrections and deeper background:

MD5crypt() did not replace the traditional DES-derived UNIX crypt(), but rather an even worse stand-in which only existed because DES was under export-control from the USA at the time. We had the DEScrypt() source, we just could not distribute it without a DoD license.

I knew at the time that hardware implementations of DES were available, and from personal experience that you didn't really need them if you took the time to hand-tweak your assembly code, so DEScrypt was not particular desirable, even if we obtained an export-license.

The choice of MD5 was driven entirely by the source-distribution issue, MD5 was published in an RFC and licensed for any use (whereas the slower, and therefore more desirable MD2 was only licensed for email.) and there were no export-control on one-way algorithms.

The things I focused most on with MD5crypt increasing the runtime in a way which could not be trivially pipelined (ie: data dependence) and on improving the environment for crypt() implementations (ie: longer salt, longer passwords, longer stored results.)

The fact that the runtime depended on the length of the password was considered and ignored: I would be more than happy with the increased security if I could get people to use 8 or 10 char passwords, never mind 17 and up, instead of just eight.

The most important thing I did was the $1$ prefix, which allowed multiple password algorithms to coexist. I pointed out at the time, that allowed you to change the algorithm at any time, as long as you also supported the old algorithms until old passwords were changed (Best practice at the time was 3-6 month between forced password changes).

...and then people did the exact opposite, they all copied & pasted MD5crypt all through the dot-com madness until a researcher told me that he estimated most passwords in eCommerce and half of all passwords in the world were protected by MD5crypt.

As for the OpenBSD people trash-talking MD5crypt:

I never aspired to be or claimed to be a cryptographer, and the **only** reason I have ended up writing some rather consequential cryptographic source code, is that the real card-carrying cryptographers seldom do so and never in a timely fashion.

Bcrypt, scrypt and Aragon2 are without dispute superior to MD5crypt() on all metrics except the most important one: MD5crypt() were there in 1994, as open source and a readily usable software component, they were not.

So yes, I felt the OpenBSD people were a little bit too snotty when they came walzing in five years later, and pissing down on me from my own shoulders felt particular unfair: I paved the road they drove on.

Otherwise: A nice writeup, and sound advice for this day and time.

PS: Here is my own write-up of md5crypts history:

By: Aaron Toponce Fri, 25 May 2018 22:29:05 +0000 Polynomial functions are defined as a function that is quadratic, cubic, quartic, quintic, etc. that involve non-negative factors of x. In other words:

f(x) = anxn + an-1xn-1 + ... + a2x2 + a1x + a0

The sha256crypt and sha512crypt functions are polynomial, because it is quadratic function.

Exponential functions are defined as a function whose variable x appears as an exponent. In other words:

g(x) = bx
By: Raphael M Fri, 25 May 2018 20:13:30 +0000 Great post but i have a question. Big-O's sha512 is polynomial, why is polynomial?

By: Aaron Toponce Fri, 25 May 2018 03:28:18 +0000 PBKDF2 is not exactly "10k iterations of SHA-256". First, PBKDF2 is an arbitrary length output function. A user may request any arbitrary amount of data. The typical usecase is to request key material, so 16 bytes, 32 bytes, and 64 bytes are most common. However, you could request 50 bytes of data, or 33 bytes, or 400 kilobytes if you wanted. SHA-256 is a fixed length digest function, that always outputs 256-bits or 32-bytes of data.

Second, PBKDF2 has a pluggable architecture. Any cryptographic hashing primitive may be used. Common functions are MD5, SHA-1, SHA-256, and SHA-512. PBKDF2 is typically used with HMAC, although if the cryptographic hashing function supports keying, like BLAKE2, then HMAC is unnecessary. SHA-256 is a static function, without any ability to plug something else into it. It's a foundational cryptographic primitive. Bruce Schneier called hashing functions the work horse of cryptography.

Thirdly, PBKDF2 requires salts to prevent rainbow table attacks on the generated output. SHA-256 does not. This doesn't prevent you from prepending or appending salts to your input, but this is something that you have to manually add as part of your application, as SHA-256 doesn't support it natively.

Finally, PBKDF2 is a complex "belt-and-suspenders" construction. The "H" in that diagram is your plugged-in hashing function (could be SHA-256, could be BLAKE2). However, SHA-256 uses the Merkle-Damgaard construction, which is a very different construction from PBKDF2.

And Chris C was correct- PBKDF2 is a sound cryptographic primitive. A homebrew design, such as "10k iterations of salted SHA-256", is not a sound cryptographic design.

By: Chris C Thu, 24 May 2018 23:54:25 +0000 @David, I think the keyword here is "homebrew". PBKDF2 does specific things between each iteration... a homebrew may not do the right thing, or anything at all.

By: David Thu, 24 May 2018 20:02:56 +0000 It's funny that you're recommending PBKDF2, but also warn against "10k iterations of salted SHA-256 etc.". PBKDF2 is exactly that - iterative hashing with a salt - and most implementations do in fact employ SHA-256.