The text means "simple" by opposition to what was used in the older traditional DES-based crypt()
where the salt was a 12-bit value, represented as exactly two characters in a restricted set. Ulrich Drepper wants to say that his creation is less picky and can take as salt any sequence of up to 16 bytes.
Though the hashing function itself can work with any bytes (including zeros, which are not special in any way for a hash function), the C code shown in the text you link to uses a string-based API:
char *
sha256_crypt (const char *key, const char *salt)
i.e. the salt will stop just before the first byte of value zero, or just after the 16th byte, whichever comes first. Moreover, the value of the salt will be part of the produced output string, so the salt had better consist in printable ASCII characters and not include the '$'
sign, since that's what is used as separator within that string.
A simple way to generate a "proper salt string" for this function is to generate a sequence of exactly 12 random bytes (taken from a good PRNG, i.e. /dev/urandom
), and encode them with Base64. This will yield 16 random characters, in an alphabet containing letters (uppercase and lowercase), digits, '+'
and '/'
-- and none other, in particular no '$'
and no troublesome control character. The salt will still have 96 bits of entropy, making salt reuse considerably improbable (so things will be fine).
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
is a perfectly fine salt; however to be an effective salt it should only be used once (or else its not really salting the password and all hashes can be attacked in parallel).crypt()
for SHA-256/512, it's cutted-off before the first NUL byte. AFAIK PHP devs have ported Dreppers code, so the perfectly fine salt you have does effectively not work. I'm trying to find out if it should work or not by the specs given.