In Linux I can create a SHA1 password hash using sha1pass mypassword. Is there a similar command line tool which lets me create sha512 hashes? Same question for Bcrypt and PBKDF2.
13 Answers
On any of the Red Hat distros such as Fedora, CentOS, or RHEL the command mkpasswd doesn't include the same set of switches as the version typically included with Debian/Ubuntu.
NOTE: The command mkpasswd is actually part of the expect package, and should probably be avoided. You can find out what package it belongs to with either of these commands.
$ yum whatprovides "*/mkpasswd"
-or-
$ repoquery -q --file */mkpasswd
Example
$ repoquery -q --file */mkpasswd
expect-0:5.43.0-8.el5.x86_64
expect-0:5.43.0-8.el5.i386
Both of these methods are superior to using rpm since the packages do not have to be installed to locate */mkpasswd.
Workarounds
To work around this you can use the following Python or Perl one-liners to generate SHA-512 passwords. Take note that these are salted:
Python (>= 3.3)
$ python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'
-or scripted-
$ python -c 'import crypt; print(crypt.crypt("somesecret", crypt.mksalt(crypt.METHOD_SHA512)))'
Python (2.x or 3.x)
$ python -c "import crypt, getpass, pwd; \
print(crypt.crypt('password', '\$6\$saltsalt\$'))"
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
Note: $6$ designates sha512. Support for this method of specifying the algorithm is dependent on support in OS level crypt(3) library function (usually in libcrypt). It is not dependent on python version.
Perl
$ perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
In these examples the password is the string "password" and the salt is "saltsalt". Both examples are using $6$ which denotes that you want crypt to use SHA-512.
-
3For the python one-liner, you can use
crypt.mksalt(crypt.METHOD_SHA512)to generate the salt instead of using a fixed one. – Jake Cobb Aug 26 '14 at 00:15 -
2
-
3Before typing a clear-text password at the command line make sure you have "ignorespace" set in HISTCONTROL (i.e., do this first on CentOS/RHEL: echo 'export HISTCONTROL="ignoredups:ignorespace"' > /etc/profile.d/histcontrol.sh && source /etc/profile.d/histcontrol.sh). Otherwise, it'll get saved in your ~/.bash_history. – Patrick Dec 03 '14 at 19:38
-
4the perl (and presumably the python) use the system function "crypt". So they aren't portable, they require a crypt function that understands the requested hash type. The OSX crypt doesn't - it just gives me back an old-style DES-encrypted string. – Dan Pritts Apr 13 '16 at 21:13
-
1@RiccardoMurri I have Python 2.7.5 and have access to
crypt.mksalton CentOS 7.1 – user12345 Jul 16 '16 at 22:09 -
@user12345 Then it must be something that CentOS has backported from Py 3.x: (1) the Python docs for 2.7 do not mention
crypt.mksalt, (2) on Ubuntu 16.04 I get the following:
– Riccardo Murri Jul 18 '16 at 08:12$ python Python 2.7.11+ (default, Apr 17 2016, 14:00:29) [...] >>> import crypt >>> help(crypt.mksalt) [...] AttributeError: 'module' object has no attribute 'mksalt' -
@Patrick Much more reliable and more memorable approach: https://www.technovelty.org/linux/skipping-bash-history-for-command-lines-starting-with-space.html . In short, set
HISTCONTROLtoignorespace, the simply precede any command you don't want stored with a space. – Basic Sep 21 '16 at 22:53 -
What about
bcryptin shell or Perl? Thecryptapproach does not seem to support that. – Richlv Oct 06 '16 at 05:32 -
Confirmed that crypt on OSX as recent as 10.11 still won't do sha512 under either python or perl. – allaryin Aug 02 '17 at 18:34
-
the mkpasswd included in expect on Centos does not do sha1 sha256 sha512 bcrypt... I am not sure why its at the top of the answer: https://core.tcl.tk/expect/artifact/8d9337848c793e85 – dfc Apr 26 '18 at 14:28
-
Same on ArchLinux
pacman -F mkpasswdit is also delivered by expect bu it's not the same utility at all. – noraj Apr 23 '22 at 18:27 -
The Python
crypt.crypt()method takes a two character salt. Note thatcrypt.crypt('password', '\$6\$saltsalt\$') == crypt.crypt('password', '\$') == '\\$UZoIyj/Hy/c'... on my machine. – cjohnson318 Dec 26 '22 at 03:31
Yes, you're looking for mkpasswd, which (at least on Debian) is part of the whois package. Don't ask why...
anthony@Zia:~$ mkpasswd -m help
Available methods:
des standard 56 bit DES-based crypt(3)
md5 MD5
sha-256 SHA-256
sha-512 SHA-512
Unfortunately, my version at least doesn't do bcrypt. If your C library does, it should (and the manpage gives a -R option to set the strength). -R also works on sha-512, but I'm not sure if its PBKDF-2 or not.
If you need to generate bcrypt passwords, you can do it fairly simply with the Crypt::Eksblowfish::Bcrypt Perl module.
- 109,670
OpenSSL has
openssl passwd -6
Help says:
$ openssl passwd --help
Usage: passwd [options]
Valid options are:
...
-6 SHA512-based password algorithm
For consistent output you can specify the salt:
openssl passwd -6 -salt <YOUR_SALT>
Output is something similar to:
$6$YOUR_SALT$q/oDR4twC1ik4RoxTJJtX.3MjenHVapkMaBbq2NcRHGQjqhIWRNcEVitYZhyIx98D7lF7qs0vLTq17X0nEr8I.
with: 6 between "$" indicating the algorithm ("-6" above), followed by YOUR_SALT and "$", finishing with the SHA512 sum.
- 461
-
(For the record, it looks like this version of openssl is not available in Debian 9) – Joril Aug 01 '20 at 11:03
-
This works also in Windows using git-for-windows/cmder/msys2 variants of openssl – Cristian Oct 17 '22 at 12:51
-
Nice. It always annoyed me to have install the
whoispackage for this. – netzego Jun 04 '23 at 08:27
You can use the doveadm utility, which is included in the dovecot package.
doveadm pw -s SHA512-CRYPT
Result example:
{SHA512-CRYPT}$6$0JvQ1LLFESzA16.I$JVdKAIq0igudTq06BMqzT9rL1gRawMPwLr9U3/kBMKUqZdONfa0wubC89C35LKl3aE16CRH57BfGb4ygPLggL1
Just cut {SHA512-CRYPT} and you'll get your SHA512 hashed string.
-
Doesn't work for me as a regular user:
doveadm(jotik): Fatal: Error reading configuration: stat(/etc/dovecot/dovecot.conf) failed: Permission denied (euid=1000(jotik) egid=100(users) missing +x perm: /etc/dovecot, we're not in group 97(dovecot), dir owned by 0:97 mode=0750)– jotik Mar 11 '19 at 06:13 -
"Permission denied" is not related to the original question. The default dovecot setting is not to let end-user read any files in the /etc/dovecot subdirectory, particularily
users(andpassword) file. Become root, and then you can see those files. – John Greene Jan 14 '20 at 18:02 -
1The point is that
doveadmcannot be run by a regular user, so this command is not a solution to the original question for someone who isn't (or cannot become) root. That someone typically isn't interested in reading any files in the /etc/dovecot directory, and shouldn't need to just in order to generate a password hash. – Tilman Schmidt Nov 04 '20 at 15:31
Run this command:
$ /sbin/grub-crypt --sha-512
then enter the word you want hashed.
-
1
-
I don't believe grub is on c7 so you can use:
python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(),crypt.mksalt(crypt.METHOD_SHA512)))'
– ucemike Nov 03 '17 at 14:37
To expand on @slm's workarounds above, if you're worried about someone getting a hold of your bash history and seeing the plain text password, you can insert raw_input() in the python statement where the salt and password fields go so it prompts you for them. The text isn't masked while you're typing, but it won't show up in your bash history. You could also start the command with a leading space, but I always forget to do that.
python -c "import crypt, getpass, pwd; print crypt.crypt(raw_input(), '\$6\$' + raw_input() + '\$')"
- 2,485
-
4You can also configure
bashto not record commands prefixed with a space addingHISTCONTROL=ignorespaceto your.bashrcfile. When you run a command you want to exclude from your history simply type a space then the actual command. – theillien Apr 10 '16 at 03:05 -
You could also use whatever tool you want and use
cat. For example,cat | the-tool-expecting-passwd-stdincan be used and after writing the password to your terminal (now connected tocat), simply press Ctrl+D after pressing enter to signal end of input. – Mikko Rantalainen Jan 08 '24 at 13:02
sha512 htpasswd
Command which asks for user and password and generates a regular htpasswd-file:
python -c 'import crypt,getpass; print(getpass.getpass("Name: ")+":"+crypt.crypt(getpass.getpass(),crypt.mksalt(crypt.METHOD_SHA512)))' >> htpasswd
Works with all python versions > 2.5.
- 183
- 6
I did the same thing with NodeJs before:
echo "console.log(require('crypto').createHmac('sha512', 'nonbase64key').update('password').digest('hex'))" | node
it's equivalent in python is:
python3 -c 'import hashlib;import base64;import hmac;print(hmac.new(b"nonbase64key", "password".encode(), hashlib.sha512).hexdigest())'
And the equivalent shell command is:
echo -n "password" | openssl sha512 -hmac "nonbase64key"
- 151
All examples will be using SHA-512, <password> as password placeholder and <salt> as salt placeholder.
mkpasswd
Note: mkpasswd binary is installed via the package whois on Debian / Ubuntu only. On other Linux distribution such as ArchLinux, Fedora, CentOS, openSUSE, etc. mkpasswd is provided by the expect package but is an totally different utility which is available as expect_mkpasswd on Debian / Ubuntu. whois of all other Linux distro doesn't include mkpasswd but the source (C lang) can be found on the original repository https://github.com/rfc1036/whois.
# With a random password and random salt
mkpasswd -m sha-512
# With a random random salt
mkpasswd -m sha-512 '<password>'
# Choosing both password and salt
mkpasswd -m sha-512 '<password>' '<salt>'
# Read password from stdin to avoid leaking it in shell command history
mkpasswd -m sha-512 --stdin
OpenSSL
# With a random random salt
openssl passwd -6 '<password>'
# Choosing both password and salt
openssl passwd -6 --salt '<salt>' '<password>'
# Read password from stdin to avoid leaking it in shell command history
openssl passwd -6 -stdin
openssl passwd -6
Ruby
# With a random password and random salt
ruby -e 'require "securerandom"; puts SecureRandom.alphanumeric(20).crypt("$6$" + rand(36 ** 8).to_s(36))'
# With a random random salt
ruby -e 'puts "<password>".crypt("$6$" + rand(36 ** 8).to_s(36))'
# Choosing both password and salt
ruby -e 'puts "<password>".crypt("$6$<salt>")'
# Read password from stdin to avoid leaking it in shell command history
ruby -e 'require "io/console"; puts IO::console.getpass.crypt("$6$" + rand(36 ** 8).to_s(36))'
Note: for those who complains that Random#rand is a PRNG, you can use the secure SecureRandom#rand but it's not very important is rand is used only to generate the salt which is publicly available in the hash at the end.
ruby -e 'require "securerandom"; puts "<password>".crypt("$6$" + SecureRandom.rand(36 ** 8).to_s(36))'
Perl
# Choosing both password and salt
perl -le 'print crypt "<password>", "\$6\$<salt>\$"'
Python
Requires Python >= 3.3
# With a random random salt
python -c 'import crypt; print(crypt.crypt("<password>", crypt.mksalt(crypt.METHOD_SHA512)))'
# Choosing both password and salt
python -c 'import crypt; print(crypt.crypt("<password>", "$6$<salt>"))'
# Read password from stdin to avoid leaking it in shell command history
python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))
grub-crypt
Note: The grub package doesn't include grub-crypt in many distros.
# With a random random salt
# Read password from stdin to avoid leaking it in shell command history
grub-crypt --sha-512
- 340
If your using the Python (>= 2.7) method from sim's answer and want to confirm your password before it generates - because you fat finger passwords...
$ python -c 'import crypt,getpass;pw=getpass.getpass(); print(crypt.crypt(pw), crypt.mksalt(crypt.METHOD_SHA512) if (pw==getpass.getpass("Confirm: ")) else exit())'
- 11
-
In the Nov 29, 2017 version of this answer, it says this works for python 2.7 (or later). The crypt module of python2.7 does not have mksalt(). Also I think you want the crypt.mksalt() call as the 2nd arg to crypt.crypt() (misplaced close paren?). – Juan Mar 05 '18 at 14:33
openssl version "OpenSSL 1.1.1” on Linux and openssl version "LibreSSL 2.6.5” on MacOS support md5_crypt.
Just run and enter password:
openssl passwd -crypt
Password:
Verifying - Password:
<results_into_a_md5_crypt_password>
or provide the plain text password directly to the CLI:
openssl password -crypt <plain_text_password_goes_here>
<results_into_a_md5_crypt_password>
- 101
-
2
cryptstill might result in insecure classic DES implementation, taking only the first eight chars of a password. You can try that withpasswd -crypt -salt oomultiple times - first usingaaaaaaaa(8xa) and then usingaaaaaaaaaa(10xa) - proofed when both lead to same password hash – Oliver Hader May 27 '20 at 14:21
PBKDF2
I wrote a simple application in Go that allows to generate PBKDF2 hash, as OpenSSL does not provide a commandline tool for that. It supports sha1, sha256, sha512 and md5.
You can build it yourself, or download released binaries in "release" section.
https://github.com/riotkit-org/gpbkdf2
The usage is very simple:
gpbkdf2 --passphrase=my-secret-passphrase --salt=my-secret-salt --digest-algorithm=sha512 --digest-rounds=10000 --length=128
-
Secrets should NEVER written to a command line. Always feed them to your program via a file or an environment variable. – Holger Jakobs Jun 28 '21 at 13:57
You can use sha512sum:
echo "password" | sha512sum
- 93,103
- 40
- 240
- 233
- 7
-
33This answer is incorrect. The command will not generate a valid SHA-512 password hash. It will simply calculate the checksum of the string password\n (note that there is also a newline in the end). Unix password hashes are salted and include a hash version code between two "$" symbols. See the answer by @slm. – zorlem Nov 27 '13 at 00:05
-
1More specifically, the problem is that while the password is somewhat obfuscated, this method is vulnerable to a https://en.wikipedia.org/wiki/Rainbow_table attack. – DepressedDaniel Feb 18 '17 at 21:43
sha1sum? – Oct 17 '12 at 18:43sha1passcommand, part of the syslinux-common package on Debian. – derobert Oct 17 '12 at 18:44sha512sumcommand that's part of coreutils, and similarlyopenssl sha512-- but neither does the extra stuff thatsha1passdoes. – Keith Thompson Oct 17 '12 at 20:37