Extending crypt/shadow (was SHA Encryption)

Jonathan Day <[email protected]> Fri, 14 Oct 2005 22:31:50 -0700
Newsgroups gmane.linux.pld.shadow.general
Message-ID <[email protected]>
Hi,

It would seem to me that instead of extending crypt() or Shadow all the 
time to support new(er) hash algorithms, it would be better to make use 
of existing hash function libraries. There seems little point in having 
a million implementations of fundamentally the same code, as then you're 
simply a million times more likely to have a buggy version somewhere.

The two "de-facto" general-purpose hash libraries out there with C 
interfaces are libgcrypt and mhash. Of these, I'd argue that mhash has a 
slightly wider range of functions and has a slightly friendlier API. It 
should not be hard to have #ifdef's to conditionally use mhash wherever 
you'd otherwise call glibc's crypt() function. The reason for this 
method is that it would be portable across systems using glibc 1 (which 
I think some of the *BSDs do still use).

A second option would be to use mhash (or some other crypto library) as 
the basis for an extended crypto module for glibc. If you were to do 
that, I'd probably add a function call to switch between hashing 
algorithms, rather than compile one directly in. That way, systems using 
certified precompiled binaries could use a decent password hashing scheme.

Regardless of method, I would be wary of "upgrading" to SHA-1. It has 
known attacks, so if you're concerned enough about having uber-strong 
passwords to use SHA over MD5, I'm not convinced it buys you a great 
deal. At this point, Whirlpool, Tiger and SHA-256 seem to be the best in 
terms of security, and (AFAICT) should be considered in that order for 
reasons of performance. (Whirlpool is a LOT faster than SHA.)

There is one other consideration. If you have support for different 
hashing algorithms, you would be able to support multiple hashing 
algorithms in use at the same time. This would be useful in cases where 
you absolutely needed to support some legacy password file or some 
legacy software that assumed some specific length of hash for the 
password. If this were to be considered seriously as an option, you'd 
want to store the method used to hash that password entry. But you'd 
have to do this in a way that was backwards-compatible, or you'd cause 
problems for the legacy software you were trying to support. Either 
that, OR you would need to sense the length of the password hash - but 
this absolutely prohibits you from ever using two algorithms that 
generate the same length of output. It would also be computationally 
more expensive than a simple lookup.

Backwards-compatibility means you'd need to use a new file or database 
table, or you'd cause problems for software that assumes that field X 
means Y and that there are exactly N fields in a row. If you were going 
to do this, you'd probably want two columns - the first for the hashing 
method of the existing password, the second for the hashing method to be 
used by a new password. That way, you could have a password algorithm 
update policy, as and when algorithms are introduced or broken.

Comments (or offers of brain surgery) welcome.