Name
vxutil_phash -- password hashing in Vitalnix
Syntax
#include <vitalnix/libvxutil/libvxutil.h>
bool vxutil_phash(const char *key, const char *salt, unsigned int algorithm, char **result);
Link with -lvxutil.
Description
vxutil_phash()
is the password hashing/encryption
function in Vitalnix.
key
is a password or any random string
that is to be hashed/encrypted.
salt
is a random string used to perturb
the algorithm in varying number of ways. Different algorithms require different
salt strings. See below for details. salt
may be
NULL
, in which case vxutil_phash()
will generate a
suitable random salt internally and use it.
The base64 set
The base64 character set is [./0-9A-Za-z
].
While non-base64 characters in the salt work in Glibc's and Vitalnix's implementations, you should not rely on this behavior, especially because database backends (such as Shadow, see vxdrv_shadow(7)) put restrictions on what characters to use. Using non-base64 characters will yield undefined results and possibly corrupts your database or the hash when the hash is inserted into the DB.
Algorithm overview
DES crypt
DES crypt is selected using the VXPHASH_DES
constant for the algorithm
argument. DES is a weak 56-bit
block cipher, and only the first eight characters of the
key
are used. The salt must be a two-character string from
the base64 character set. Vitalnix relies on libc/libcrypt to provide the
implementation of this algorithm, so it is not available, for example, under
Microsoft Windows. Use of DES is discouraged.
MD5 hash
MD5 hashing is selected using the VXPHASH_MD5
constant. Both the key and salt (full length, unlike DES) are used to build the
128 bit digest.
The salt consits of a ID prefix, the salt and optionally a
dollar sign. The ID is the three-character string "$1$
", and the
salt is string of base64 characters with minimum length 0 and maximum length 8.
It will automatically be truncated if it is longer than this. Valid salts would
be, for example, "$1$
", "$1$$
", "$1$ABC
"
and "$1$longerthaneight$
".
Blowfish crypt
Blowfish crypt is selected using
VXPHASH_BLOWFISH
. It features a highly complex key schedule and
its number of rounds is tunable, which makes it fit for the long-term use.
The salt consists of the ID prefix "$2a$
", a salt
string of exactly 22 base64 characters and an optional dollar sign.
NT4 hash
Windows NT hashing is selected using
VXPHASH_SMBNT
. The salt
argument is ignored.
The NT4 hash is a simple 128-bit MD4 digest of the key
with
a few static transformations without any salt perturbation, and hence is
susceptible to dictionary and rainbow attacks. I discourage its use, though
unfortunately, Windows clients rely on this.
SHA-256 hash
The SHA family of password hashing has been introduced just recently (September 2007) as a successor to the DES crypt and MD5 hash methods. It works similarly to the MD5 variant, but like Blowfish, the number of rounds can also be tuned.
The SHA-256 hash method can be selected using
VXPHASH_SHA256
. The salt string is made up of the ID
"$5$
", an optional rounds parameter
"rounds=N$
", up to 16 base64 characters and an optional
dollar sign. The number of rounds, if provided, must be between 1,000 and
999,999,999 (inclusive). If it exceeds these limits, the value will be clamped.
A valid example: $5$rounds=5000$abcdefghijklmnop$
SHA-512 hash
The SHA-512 hash method can be selected using
VXPHASH_SHA512
. Its ID is "$6$
" and also allows a
rounds parameter and uses 16 base64 characters.
Return value
vxutil_phash()
will return a boolean, indicating
either success or failure. On success, *result
is filled
with a pointer to an allocated region of memory containing the hash, which you
are supposed to free when you are done with it.
Failure may arise if the wanted algorithm is not available or
a memory allocation failure occurred. The contents of the
errno
variable are undefined.
Example
char *result = NULL;
if (vxutil_phash("password", "$2a$05$ABCDEFGHIJKLMNOPQRSTUV$", VXPHASH_BLOWFISH, &result)) {
printf("%s\n", result);
free(result);
}