Skip to content
Performs the UNIX crypt(3) algorithm in Ruby using DES, MD5, SHA256 or SHA512
Pull request Compare This branch is 19 commits ahead, 24 commits behind mogest:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.




unix-crypt makes and validates passwords of the form found in shadow files or LDAP. For more information

>> man 3 crypt

It is written entirely in Ruby and requires only 'digest' from the standard library. It will make use of 'securerandom' if available for salt generation. The tests run nearly twice as fast on Ruby >= 1.9.x

It makes and validates

  • DES passwords (the standard unmarked 13 character password with a 2 character salt)

  • MD5 passwords (prefixed with $1$, length 22)

  • SHA256 passwords (prefixed with $5$, length 43)

  • SHA512 passwords (prefixed with $6$, length 86)

Unless your computer is moon powered, ditch DES

>> grep ENCRYPT_METHOD /etc/login.defs

Tested on

  • ruby-1.8.7p249

  • ruby-1.9.2p0


You can either validate a password matches its hash;

>> UnixCrypt.valid?("Hello world!", "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5")
=> true

Or you can generate a new hash, given a password and salt;

>>"Hello world!", "saltstring")
=> "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5"

The #mkpasswd function is a wrapper for #build, and optionally takes the arguments :salt and :rounds;

>> UnixCrypt::MD5.mkpasswd('mypass')
=> "$1$bobkbEpx$JuZ6AsBfd3G9hCLYZ1KDE."

Simple string interpolation can make this LDAP friendly;

>> "\{crypt\}#{UnixCrypt::SHA256.mkpasswd("mypass")}"
=> "{crypt}$5$2n4C.bLL..Vknx6B$/kYmXhYDbVIoDEIRL4HqhpUoO0qQqKFIXVizgax.sI7"

Each hash type has sensible defaults that are known to work with crypt(3), however you are free to experiment;

>> UnixCrypt::SHA256.mkpasswd("mypass", :salt => "foodoo")
=> "$5$foodoo$kfqi/wcRNkTQw0v.ftfjvwwsFmhiftHmKzSORVsiae1"

>> UnixCrypt::SHA256.mkpasswd("mypass", :salt => "foodoo", :rounds => 54321)
=> "$5$rounds=54321$foodoo$bwF37grDS6PE3yfHZeaj1mycDkK8k0wEfRuXXMBcR.9"

If you go nuts with the rounds, be prepared to wait ;]

>> UnixCrypt::SHA512.mkpasswd("mypass", :rounds => 5_000_000)
=> "$6$rounds=5000000$0gHHePm/AY9F2KNn$bxfZxe/5ceY.v0rx3ShrD.V5v9/QPk/CsWPSszK.gT6oUHqB1VcQpyGYGf3lNGg7dT7UbunFk5qkzGlL9uT4N1"

>> UnixCrypt.valid?("mypass", "$6$rounds=5000000$0gHHePm/AY9F2KNn$bxfZxe/5ceY.v0rx3ShrD.V5v9/QPk/CsWPSszK.gT6oUHqB1VcQpyGYGf3lNGg7dT7UbunFk5qkzGlL9uT4N1")
=> true

unix-crypt can generate salts itself - or you can use your favourite random number generator;

>> UnixCrypt.make_salt
=> "FWekKY/Ovu34TiRv"

>> UnixCrypt.make_salt(32)
=> "ePfqWKPD7LGyfBNFpsVpKUh7vUKXgsv0"

Using #mkpasswd without a :salt argument will cause UnixCrypt#make_salt to be used.

Note: UnixCrypt#secure_random? will return a boolean to indicate if 'securerandom' is in use.


Licensed under the BSD license. See LICENSE file for details.

Something went wrong with that request. Please try again.