Comments on: Do Not Use sha256crypt / sha512crypt - They're Dangerous Linux. GNU. Freedom. Fri, 08 Mar 2019 12:16:08 +0000 hourly 1 By: yvain Fri, 08 Mar 2019 12:16:08 +0000 Wery well

By: Christopher K. Wed, 30 Jan 2019 21:27:43 +0000 Interesting article. Obviously, your recommendations are right. But still, your heading is largely misleading and - in my opinion- mostly click-bating. Where in your article do you explain why sha256crypt / sha512crypt are "dangerous"?

Your first argument is that you could DOS an authentication server with huge passwords. Have you ever heard of that? I believe most servers have other software that you can DOS a lot more easily, but let's consider that and compare to the alternatives. Assume I was an attacker trying to DOS your authentication server. What I could do, depending on your hashing algorithm (numbers taken/calculated from your plots, assuming they are comparable):

sha512crypt: send a 4kb password that causes 0.3s execution time and 1 "process" on the server and costs me 4kb of traffic to transfer the password

PBKDF2-HMAC-SHA512: send 167 passwords with one byte each that causes 0.3s execution time on the server (167 * 0.0018s), needs 167 "processes" on the server (threads, tcp connections, database connections, whatever that server does while checking authentication), and costs me 167 bytes of traffic to transfer passwords

bcrypt: send 137 passwords with one byte each that causes 0.3s execution time and 137 processes on the server and costs me 137 bytes of traffic to transfer passwords

scrypt: send 7 passwords with one byte each, 0.3s execution time, 7 processes used and 7 bytes of traffic

argon2: send 8 passwords with one byte each, 0.3s execution time, 8 processes used and 8 bytes of traffic

Sure, modern algorithms are better and more secure. But they need more execution time for small passwords and thus, make it easier to brute force, not more difficult. The attacker could more easily send 7 one byte passwords to scrypt than one 4kb to sha512crypt. Usually the uplink of the attacker is a bottleneck, so sending 4kb passwords seems to be a bad idea. Plus, which real-world authentication system supports 4kb passwords?

"moderately large passwords from staff, where such limits may not be imposed, could create a CPU denial of service on busy authentication servers."
Staff would most likely first use VPN/SSH with ("large") key files to get into the internal network and then passwords of normal length.

This is only "dangerous" in theory. And even in theory, other hashing functions seem to be more attractive in terms of DOSing them.

The second argument you mention are timing attacks. I would give this the bigger concern, because it really affects security. But as you mention yourself, it does not make much difference as most real-world passwords fall into the same category. Furthermore, it is difficult to do these kind of timing attacks on a server without getting blocked due to brute-forcing.

So in summary: Yes, modern algorithms are better, but what you write does not explain why sha256crypt/sha512crypt are *dangerous*.

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.