*NIX shadow file password format

The most common format for hashes on Unix-like systems has the form $ALG$SALT$OUTPUT where ALG is a small number identifying the algorithm, SALT is a salt for the hash and OUTPUT is the output of the hash function. SALT and OUTPUT are encoded in base64.

Algorithm 1 is “MD5 crypt”, a construct based on iterating the MD5 hash function. This algorithm was not (and still isn't, as far as I know) defined by a formal standard. It was introduced by Poul-Henning Kamp in FreeBSD in 1994.

Normal APIs add a salt. The original implementation forced a 48-bit salt. The iteration count is fixed to 2477, which the author benchmarked for 34µs on a high-end PC of the time. Your hash has an empty salt, which is unusual and required the developer or administrator who configured it to bypass the usual tools and probably call a library function directly.

Current Linux systems usually use algorithms 5 and 6, which are based on iterating SHA-256 and SHA-512 respectively. These constructs are broadly based on the same principle as PBKDF2, but compute the iterated hash differently.

You can find a wealth of information about password hash algorithms in the documentation of the passlib library, and of course the library gives you Python implementations. This algorithm is passlib.hash.md5_crypt.


Assuming the router follows the glibc standard for password hashes, the second field ($1$$N76hdwGfg11g0KdKbtyh21) is the password, and is encoded as follows:

  • $1$: iterated MD5 hash
  • $: No salt
  • N76hdwGfg11g0KdKbtyh21: the hashed password, in base64 encoding. In hex encoding, it would be 37bea177019f835d60d0a74a6edca1db