Contributed by Garrett Wollman
<wollman@FreeBSD.org>
24 September 1995.
History
In order to protect the security of passwords on UN*X systems from being easily exposed, passwords have traditionally been scrambled in some way. Starting with Bell Labs' Seventh Edition Unix, passwords were encrypted using what the security people call a ``one-way hash function''. That is to say, the password is transformed in such a way that the original password cannot be regained except by brute-force searching the space of possible passwords. Unfortunately, the only secure method that was available to the AT&T researchers at the time was based on DES, the Data Encryption Standard. This causes only minimal difficulty for commercial vendors, but is a serious problem for an operating system like FreeBSD where all the source code is freely available, because national governments in many places like to place restrictions on cross-border transport of DES and other encryption software.
So, the FreeBSD team was faced with a dilemma: how could we provide
compatibility with all those UNIX systems out there while still not
running afoul of the law? We decided to take a dual-track approach:
we would make distributions which contained only a non-regulated
password scrambler, and then provide as a separate add-on library the
DES-based password hash. The password-scrambling function was moved
out of the C library to a separate library, called `libcrypt
'
because the name of the C function to implement it is
`crypt
'. In FreeBSD 1.x and some pre-release 2.0 snapshots,
the non-regulated scrambler uses an insecure function written by Nate
Williams; in subsequent releases this was replaced by a mechanism
using the RSA Data Security, Inc., MD5 one-way hash function. Because
neither of these functions involve encryption, they are believed to be
exportable from the US and importable into many other countries.
Meanwhile, work was also underway on the DES-based password hash
function. First, a version of the `crypt
' function which was
written outside the US was imported, thus synchronizing the US and
non-US code. Then, the library was modified and split into two; the
DES `libcrypt
' contains only the code involved in performing
the one-way password hash, and a separate `libcipher
' was
created with the entry points to actually perform encryption. The
code was partitioned in this way to make it easier to get an export
license for the compiled library.
Recognizing your `crypt
' mechanism
It is fairly easy to recognize whether a particular password
string was created using the DES- or MD5-based hash function.
MD5 password strings always begin with the characters
`$1$
'. DES password strings do not have
any particular identifying characteristics, but they are shorter
than MD5 passwords, and are coded in a 64-character alphabet
which does not include the `$
' character, so a
relatively short string which doesn't begin with a dollar sign is
very likely a DES password.
Determining which library is being used on your system is fairly
easy for most programs, except for those like `init
' which
are statically linked. (For those programs, the only way is to try
them on a known password and see if it works.) Programs which use
`crypt
' are linked against `libcrypt
', which for
each type of library is a symbolic link to the appropriate
implementation. For example, on a system using the DES versions:
$ cd /usr/lib
$ ls -l /usr/lib/libcrypt*
lrwxr-xr-x 1 bin bin 13 Sep 5 12:50 libcrypt.a -> libdescrypt.a
lrwxr-xr-x 1 bin bin 18 Sep 5 12:50 libcrypt.so.2.0 -> libdescrypt.so.2.0
lrwxr-xr-x 1 bin bin 15 Sep 5 12:50 libcrypt_p.a -> libdescrypt_p.a
On a system using the MD5-based libraries, the same links will be
present, but the target will be `libscrypt
' rather than
`libdescrypt
'.