I need to manually edit /etc/shadow to change the root password inside of a virtual machine image.

Is there a command-line tool that takes a password and generates an /etc/shadow compatible password hash on standard out?

up vote 106 down vote accepted

You can use following commands for the same:

Method 1

openssl passwd -1 -salt xyz  yourpass

Method 2

makepasswd --clearfrom=- --crypt-md5 <<< YourPass

Method 3

As @tink suggested, we can update password using chpasswd using :

echo "username:password" | chpasswd 

Or you can use encrypted password with chpasswd. First generate it using this:

perl -e 'print crypt("YourPasswd", "salt"),"\n"'

Then later you can use generated password to update:

echo "username:encryptedPassWd"  | chpasswd -e

This encrypted password we can use to create a new user with password, for example:

useradd -p 'encryptedPassWd'  username

Method 4

echo -e "md5crypt\npassword" | grub | grep -o "\$1.*"

Method 5

perl -e 'use Crypt::PasswdMD5; print unix_md5_crypt("Password", "Salt"),"\n"'

This one is used by makepasswd, but allows more versatility (like custom or empty salt).

  • 3
    When using chpasswd -e, make sure to use single quotes on the string you echo in; otherwise, if there are $ or other special characters, they will not get treated literally. – Zags Oct 15 '14 at 19:28
  • 4
    Note that make of these will end up in your shell history. I would use openssl passwd -1 which 1) doesn't end up there and 2) generates a random salt for you (which doesn't end up in shell history, neither). – Ztyx Sep 22 '15 at 12:20
  • 1
    openssl passwd documenation for anyone trying to figure out what the -1 option does. – CivFan Oct 29 '15 at 21:55
  • 3
    For a SHA-512 hash: python3 -c 'import crypt; print(crypt.crypt("test", crypt.mksalt(crypt.METHOD_SHA512)))' - from related ServerFault question – CivFan Oct 29 '15 at 22:47
  • 7
    Method 1) and 2) above uses MD5 for hashing. MD5 isn't considered best practise anymore as there has been hash collisions. Use method 3) or the one described in unix.stackexchange.com/a/198906/10911. – Ztyx Jan 11 '16 at 9:04

On Ubuntu 12.04, there is mkpasswd (from the whois package): Overfeatured front end to crypt(3)

mkpasswd  -m sha-512 -S saltsalt -s <<< YourPass

Where:

  • -m = Compute the password using the TYPE method. If TYPE is help then the available methods are printed.
  • -S = salt used.

E.g.

$ mkpasswd -m help

-s = Read password from stdin
  • 7
    There's no need to specify the salt, mkpasswd takes care of generating a random one. – To마SE May 23 '16 at 20:03
  • No matter what, generated passwords from mkpasswd copied into the /etc/passwd always fail. Is there a way to check if the hash created by mkpasswd is correct? – CMCDragonkai Mar 8 at 5:36
  • @CMCDragonkai: Wrong question. You need to ask what your system is expecting. – user3183018 Mar 8 at 16:11
  • @To마SE: It is somtimes useful to control the salt. I have used it when testing hash generation of passwords for web app where I was storing the salt in a separate store. E.g. hashed password in MySQL DB, and per user salt in Redis. – user3183018 Mar 8 at 16:13

This solution has the following benefits:

  • Nothing additional to install
  • Does not store the password in your shell history
  • Generates a random salt for you
  • Uses a modern, strong hashing algorithm, SHA-512
  • Re-prompts for the password to avoid mistakes.

    $ python3 -c "from getpass import getpass; from crypt import *; \
        p=getpass(); print('\n'+crypt(p, METHOD_SHA512)) \
        if p==getpass('Please repeat: ') else print('\nFailed repeating.')"
    

References

None of the current methods are acceptable to me - They either pass the password on the command line (which ends up in my shell's history), require the installation of additional utilities (python3, makepasswd), use hard-coded salts or use old hashing techniques.

This method would generate SHA-512 hashes after prompting for the password and would use a random salt.

A method utilising Python 2 without any non-standard libraries:

python2 -c 'import crypt, getpass,os,base64; print crypt.crypt(getpass.getpass(), "$6$"+base64.b64encode(os.urandom(16))+"$")'

To do it without a prompt: (This will leave your password in the command history)

python2 -c 'import crypt, os,base64; print crypt.crypt("MyPassword", "$6$"+base64.b64encode(os.urandom(16))+"$")'
  • To avoid leaving the password in the command history, you can set (for bash, at least) the environment variable HISTCONTROL to 'ignorespace', and then add a leading space in front of the command. – adam820 Oct 4 at 17:00
  • @adam820: That is one way... It would still it in the ps output in the fraction of a second that the command is running. (The safest remains to use the version that prompts for the password) – Gert van den Berg Oct 5 at 6:10

For those without Debian based systems. Python3 works just as well.

python3 -c 'import crypt; print(crypt.crypt("test"))'

NOTE: The string "test" is the password that we're generating as a crypted string.

  • For some reason, using crypt.mksalt does not work when generating passwords for /etc/shadow. But @Alex131089's method works! – maulinglawns Jul 22 '17 at 16:32
  • Just wasted 1.5h trying this method, before I noticed the comment. Can somebody remove it? I can't downvote yet. – Michał F Sep 29 '17 at 21:08
  • 1
    @MichałF it seems like this wasn't working because the salting wasn't done correctly. Thanks for pointing this out. I've removed the salt because the salting is dependent on OS and it's not practical to account for all ranges of OS in my answer. You should be using Method 1 outlined by @RahulPatil because it allows you to use salting and openssl is a pretty universal tool. – Greg Sep 29 '17 at 21:29
  • Not advisable, as it leaves your password in your shell history. – Mark Stosberg Mar 28 at 15:00
  • I mean, you can always clear the cmd from your shell history – Greg Aug 21 at 5:20

The openssl and chpasswd -e pair didn't work in my case in RHEL6. Combining "openssl passwd" and "usermod -p" command did the job.

Generate hash value of password along with salt value.

$ openssl passwd -1 -salt 5RPVAd clear-text-passwd43

$1$5RPVAd$vgsoSANybLDepv2ETcUH7.

Then, copy the encrypted string to usermod. Make sure to wrap it with single quote.

$ usermod -p '$1$5RPVAd$vgsoSANybLDepv2ETcUH7.' root

Check it out in shadow file.

$ grep root /etc/shadow

root:$1$5RPVAd$vgsoSANybLDepv2ETcUH7.:17774:0:99999:7:::

Expanding a bit on the criticisms of u150825 and Gert van den Berg, I found myself needing something relatively flexible for different situations with different automation systems. I decided I would add to my own little library of useful scripts and write this. It uses only native libraries from python 2.7+, and works on python3 just as well.

You can pick it up here if you like. It's just as easy to drop this in your environment if you're needing to use it a lot, http hosted or whatever, and you can run it on any platform using whatever the default python interpreter you've got available to you is, pretty reliably counting on it working.

It defaults to prompting using getpass with prompts on stderr (allowing easy capture of stdout), but if you pipe a string to it it'll just reap from stdin. Depending on how you're going about this, it may not be showing up in command history, either, so just be cognizant of what it is you're working with. I like having a flexible tool that'll behave in an expected way, rather than having to rely on packages or python one-lining my way to victory 10 different ways.

  • Whether python in whatever version is already installed or not depends on the system. What exactly is the problem with chpasswd? – RalfFriedl Sep 3 at 21:12

Yet another method to generate passwords, is using the openssl tool.

Generate MD5 passwords

openssl passwd -1 -salt SaltSalt SecretPassword
# output: $1$SaltSalt$FSYmvnuDuSP883uWgYBXW/

Generate DES passwords

openssl passwd -crypt -salt XR SuprScrt
# output: XR1dOp2EVMph2
  • 3
    How is this different from method 1 in Rahul Patil's answer? Note that the old DES-based password hashing algorithm definitely should not be used! For one thing, it only supports passwords of up to eight bytes, which is woefully inadequate these days. – a CVn May 30 '16 at 12:52
  • 3
    Quoting Snowden: "Assume your adversary is capable of one trillion guesses per second." With a not totally unreasonable 70-characters charset and a fully random password, that's 576 seconds -- less than ten minutes. Even against a less capable but determined adversary, it is woefully inadequate. – a CVn May 30 '16 at 12:52
  • This is not very secure, because MD5 and DES... – AdamKalisz Aug 30 at 11:48

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.