Create Portable crypt(3) Password Hashes with mkpasswd

mkpasswd generates a repeatable crypt(3) password hash without ever putting the clear-text password on the command line. The examples use mkpasswd 5.5.22 from the Debian whois package, installed on this machine.

Allow about ten minutes. You need a shell and the whois package. This guide generates hash text only: it does not create a user, edit /etc/shadow, change a login password or require elevated privileges.

Security boundary: The sample password is deliberately fictional. Do not replace it with a real password in a command line, because command arguments can be exposed through shell history or process inspection.

1. Confirm the installed command

Check which executable will run and record the package version. These are ordinary read-only commands:

$ command -v mkpasswd
/usr/bin/mkpasswd
$ dpkg-query -W -f='${Package} ${Version}\n' whois
whois 5.5.22
$ mkpasswd --version
mkpasswd 5.5.22

Checkpoint: if command -v returns nothing, install the distribution package that provides mkpasswd before continuing. Do not download a replacement script with the same name into a directory earlier in your PATH.

2. See which methods this build supports

Ask the program for its method list. The output is implementation-dependent, so use the list from the machine where the hash will actually be checked:

$ mkpasswd --method=help
Available methods:
yescrypt        Yescrypt
gost-yescrypt   GOST Yescrypt
scrypt          scrypt
bcrypt          bcrypt
bcrypt-a        bcrypt (obsolete $2a$ version)
sha512crypt     SHA-512
sha256crypt     SHA-256
sunmd5          SunMD5
md5crypt        MD5
bsdicrypt       BSDI extended DES-based crypt(3)
descrypt        standard 56 bit DES-based crypt(3)
nt              NT-Hash

Use an explicit method when another system expects a particular crypt(3) format. Leave the method out and the library picks its own default, which can change after a package or system upgrade. The names above are what this installed version accepts; do not assume every host supports all of them.

3. Generate a hash without putting the password in the command

Pipe a fictional value to standard input and select SHA-512 crypt. The command reads the password from file descriptor 0 and prints only the hash when that descriptor is not a terminal:

$ printf '%s\n' 'Example-only-password' | mkpasswd --stdin --method=sha512crypt
$6$goei7akPQLa1op1a$N.e0h/LCHSqejIvINi6lRLQhPMgEap2Kags2VASGYua0/R932aQRxYZ6/NjY2XuPnW6I9Hcn9mvaN0Tkp9U8C.

Your own output will normally differ, because mkpasswd generates a random salt when none is supplied. That is expected and desirable: equal passwords should never automatically produce equal stored hashes.

In a real script, prefer a protected input channel owned by the caller rather than embedding a password in the script itself. The --stdin option has a documented limitation: some control characters are not read correctly, so ordinary newline-terminated text is the safe shape here.

4. Reproduce a hash when a fixed salt is genuinely required

Most password storage should use a random salt. A fixed salt is useful for a test fixture or compatibility check, but it makes repeated output predictable and should not be used as a general password-storage policy:

$ printf '%s\n' 'Example-only-password' | mkpasswd --stdin --method=sha512crypt --salt='$6$examplesalt$'
$6$examplesalt$mjZbvQV5ONTItNVDrtmhysaP6xE.wD4UacpYVSex0dYZCErDWozuAIGh2aHlFQU4H.NOMuIGQVAkLlZIjAKbK.

The $ characters are protected by single quotes so the shell does not expand them. The method-specific salt prefix is part of the crypt format. Passing an invalid salt, or a salt meant for another method, can produce an error or an unusable result. Treat the hash as sensitive authentication material even though it does not reveal the original password directly.

5. Set rounds only with a method that supports them

The --rounds option changes the work factor for methods that support variable rounds. Pair it with --method: the manpage leaves behaviour undefined when rounds are used without one:

$ printf '%s\n' 'Example-only-password' | mkpasswd --stdin --method=sha512crypt --rounds=10000
$6$rounds=10000$DgpXdHDqV5XVE0TW$GhBRMoTVTTwvzVJtmLMKRdHUErD6MgRFbcCcQMy0djvBFzLLdN5ANygnLaIEa8zAo7p/5LRkO33Vw7b4dFbNP.

Here the rounds marker is visible in the result, so a verifier can use the work factor recorded in the hash. The option is ignored for methods without variable rounds. Do not choose a large value blindly: it affects authentication cost for every verification, so test it on the target hardware first.

Checkpoint: verify the command's status immediately after it runs:

$ printf '%s\n' 'Example-only-password' | mkpasswd --stdin --method=sha512crypt > /tmp/mkpasswd-example.hash
$ status=$?
$ printf 'mkpasswd status: %s\n' "$status"
mkpasswd status: 0

The temporary file contains a password hash and should not be left behind. Remove this example file after inspection:

$ rm -- /tmp/mkpasswd-example.hash

This is the only state-changing command in the guide, and it removes the temporary output created by the preceding example. If you saved a real hash elsewhere, delete it only after confirming that no account or deployment still needs it.

6. Avoid the common traps

Done means