crypt(p1) public

Returns the string generated by calling crypt(3) standard library function with str and salt_str, in this order, as its arguments. Please do not use this method any longer. It is legacy; provided only for backward compatibility with ruby scripts in earlier days. It is bad to use in contemporary programs for several reasons:

* Behaviour of C's crypt(3) depends on the OS it is
  run.  The generated string lacks data portability.

* On some OSes such as Mac OS, crypt(3) never fails
  (i.e. silently ends up in unexpected results).

* On some OSes such as Mac OS, crypt(3) is not
  thread safe.

* So-called "traditional" usage of crypt(3) is very
  very very weak.  According to its manpage, Linux's traditional
  crypt(3) output has only 2**56 variations; too
  easy to brute force today.  And this is the default behaviour.

* In order to make things robust some OSes implement so-called
  "modular" usage. To go through, you have to do a complex
  build-up of the salt_str parameter, by hand.
  Failure in generation of a proper salt string tends not to
  yield any errors; typos in parameters are normally not
  detectable.

    * For instance, in the following example, the second invocation
      of String#crypt is wrong; it has a typo in
      "round=" (lacks "s").  However the call does not fail and
      something unexpected is generated.

         "foo".crypt("$5$rounds=1000$salt$") # OK, proper usage
         "foo".crypt("$5$round=1000$salt$")  # Typo not detected

* Even in the "modular" mode, some hash functions are considered
  archaic and no longer recommended at all; for instance module
  $1$ is officially abandoned by its author: see
  http://phk.freebsd.dk/sagas/md5crypt_eol.html .  For another
  instance module $3$ is considered completely
  broken: see the manpage of FreeBSD.

* On some OS such as Mac OS, there is no modular mode. Yet, as
  written above, crypt(3) on Mac OS never fails.
  This means even if you build up a proper salt string it
  generates a traditional DES hash anyways, and there is no way
  for you to be aware of.

      "foo".crypt("$5$rounds=1000$salt$") # => "$5fNPQMxC5j6."

If for some reason you cannot migrate to other secure contemporary password hashing algorithms, install the string-crypt gem and require ‘string/crypt’ to continue using it.

Show source
Register or log in to add new notes.
May 4, 2009
1 thank

clarification

Via Kenneth Kalmer:

From the man page: If salt is a character string starting with the characters “$id$” followed by a string terminated by “$”: $id$salt$encrypted then instead of using the DES machine, id identifies the encryption method used and this then determines how the rest of the password string is interpreted.

irb session

=>abNANd1rDfiNc”
irb(main):002:0>secret”.crypt(”abasasa”)
=>abNANd1rDfiNc”
irb(main):003:0>secret”.crypt(”$1$abasasa”)
=>$1$abasasa$2RZY2vd6E2ZEPSDa0eLec0″
irb(main):004:0>secret”.crypt(”$1$abasa”)
=>$1$abasa$ikoKICgwOFdcWgmDl9Asy1″

see http://www.opensourcery.co.za/2009/05/01/quick-nix-shadow-passwords-with-ruby/

March 3, 2011
1 thank

String#crypt uses your platform's native implementation

Which cipher types (specified through the salt argument) are available will depend on what your platform natively supports. It should be noted that OSX up to at last 10.6 only provides the regular DES cipher. On most Linux platforms, however, you should have access to the following:

ID  | Method
---------------------------------------------------------
1   | MD5
2a  | Blowfish (not in mainline glibc; added in some
    | Linux distributions)
5   | SHA-256 (since glibc 2.7)
6   | SHA-512 (since glibc 2.7)

So on OSX, you might have:

ruby-1.9.2-p180 :001 > "password".crypt("$6$somesalt")
 => "$6FMi11BJFsAc" 

But on Linux, you’ll get:

irb(main):001:0> "password".crypt("$6$somesalt")
=> "$6$somesalt$A7P/0Yfu8RprY88D5T1n.xKT749BOn/IXBvmR1gXZzU7imsoTfZhCQ1916CB7WNX9eOOeSmBmmMrl5fQn9LAP1"

For more information on what your platform supports, see `man crypt`

February 11, 2010 - (v1_8_6_287 - v1_8_7_72)
0 thanks

Clarification of argument

The description should read:

The argument is the salt string, which must be at least two characters long, each character drawn from [a-zA-Z0-9./].

December 7, 2012
0 thanks

Beware: default system crypt functionality silently ignores characters beyond the 8th

On some systems:

"1".crypt('aa')                     => "aacFCuAIHhrCM"
"12".crypt('aa')                    => "aa8dJzr7DFMPA"
"123".crypt('aa')                   => "aamrgyQfDFSHw"
"1234".crypt('aa')                  => "aatxRPdZ/m52."
"12345".crypt('aa')                 => "aajt.4s3e3SZA"
"123456".crypt('aa')                => "aaAN1ZUwjW7to"
"1234567".crypt('aa')               => "aaOK9MRbwVNmQ"
"12345678".crypt('aa')              => "aaNN3X.PL2piw"
"123456789".crypt('aa')             => "aaNN3X.PL2piw"
"1234567890".crypt('aa')            => "aaNN3X.PL2piw"
"1234567890abcdefghij".crypt('aa')  => "aaNN3X.PL2piw"