Perl / perl5

đŸȘ The Perl programming language
https://dev.perl.org/perl5/
Other
1.92k stars 549 forks source link

crypt produces same digest for different strings #11250

Closed p5pRT closed 13 years ago

p5pRT commented 13 years ago

Migrated from rt.perl.org#88362 (status was 'rejected')

Searchable as RT88362$

p5pRT commented 13 years ago

From perl@renee-baecker.de

Hi\,

Shouldn't crypt produce different results for different input?

entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.10.1/bin/perl -E 'say crypt "longtext"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.10.1/bin/perl -E 'say crypt "longtext01"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.12.2/bin/perl -E 'say crypt "longtext"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.12.2/bin/perl -E 'say crypt "longtext01"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.13.11/bin/perl -E 'say crypt "longtext"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.13.11/bin/perl -E 'say crypt "longtext01"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$

And with Perl 5.8.9 on Windows (and same for Perl 5.10.1 on Windows) C​:\Users\Entwicklung>perl -le "print crypt 'longtext'\, 'BR'" BRjuHtYRmCGCc C​:\Users\Entwicklung>perl -le "print crypt 'longtext01'\, 'BR'" BRjuHtYRmCGCc C​:\Users\Entwicklung>perl -le "print crypt 'longtext0101'\, 'BR'" BRjuHtYRmCGCc C​:\Users\Entwicklung>perl -le "print crypt 'longtext010101'\, 'BR'" BRjuHtYRmCGCc C​:\Users\Entwicklung>perl -le "print crypt 'longtext010101asfgefasdfvwe'\, 'BR'" BRjuHtYRmCGCc

C​:\Users\Entwicklung>perl -le "print crypt 'long'\, 'BR'" BRd//sarKVX2Q C​:\Users\Entwicklung>perl -le "print crypt 'longt'\, 'BR'" BRLfnUI8Zi2N6 C​:\Users\Entwicklung>perl -le "print crypt 'longte'\, 'BR'" BRQmLsxZsq4ZA C​:\Users\Entwicklung>perl -le "print crypt 'longtex'\, 'BR'" BRepwQxfejBos C​:\Users\Entwicklung>perl -le "print crypt 'longtext'\, 'BR'" BRjuHtYRmCGCc C​:\Users\Entwicklung>perl -le "print crypt 'longtext0'\, 'BR'" BRjuHtYRmCGCc

From perldoc​:   crypt PLAINTEXT\,SALT   [...] Small changes in the PLAINTEXT or SALT will result in   large changes in the digest.

p5pRT commented 13 years ago

From @Leont

2011/4/12 Renee BĂ€cker \perlbug\-followup@​perl\.org​:

Shouldn't crypt produce different results for different input?

From «man crypt»​:   By taking the lowest 7 bits of each of the first eight characters of the key\, a 56-bit key is obtained.

It's behaving exactly as expected. It's also cryptographically useless nowadays.

Leon

p5pRT commented 13 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 13 years ago

From zefram@fysh.org

Renee B??cker wrote​:

Shouldn't crypt produce different results for different input?

If it were a good algorithm then yes. But crypt() is specifically the algorithm historically used under that name in Unix\, and one of its features is that it only looks at the first eight bytes of the password. The output you're seeing is correct.

If you're building a new system\, rather than requiring compatibility with the historical crypt()\, you should use a modern hashing scheme. Here's what I wrote about crypt() in the documentation for its implementation in my Authen​::Passphrase suite (Authen​::Passphrase​::DESCrypt)​:

  Warning​: this password scheme is weak by modern standards\, and in any   case does not support a large password space. Cracking crypt()ed   passwords has been a routine activity since the early 1990s. This   scheme is supported for compatibility reasons only\, and should not be   used except when compatibility is required. Do not use this in the   design of any new system or for new passwords in any system that   supports better passphrase schemes.

I generally recommend using salted SHA-1 in new systems\, as implemented by Authen​::Passphrase​::SaltedDigest. That recommendation will change when the SHA-3 process finishes.

-zefram

p5pRT commented 13 years ago

From @tonycoz

On Tue\, Apr 12\, 2011 at 05​:04​:10AM -0700\, Renee BĂ€cker wrote​:

entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.10.1/bin/perl -E 'say crypt "longtext"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.10.1/bin/perl -E 'say crypt "longtext01"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.12.2/bin/perl -E 'say crypt "longtext"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.12.2/bin/perl -E 'say crypt "longtext01"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.13.11/bin/perl -E 'say crypt "longtext"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ perl-5.13.11/bin/perl -E 'say crypt "longtext01"\, "BR"' BRjuHtYRmCGCc entwicklung@​ubuntu​:\~/perl5/perlbrew/perls$ ...

From perldoc​: crypt PLAINTEXT\,SALT [...] Small changes in the PLAINTEXT or SALT will result in large changes in the digest.

Classic DES crypt() only works with the first 8 characters of the plaintext\, and since the results are cross-platform\, that can't be changed.

More modern crypt() implementations support alternative hashing mechanisms​:

tony@​mars​:\~$ perl -le 'print crypt("longtext"\, q($1$abcdef))' $1$abcdef$cJYhHJfpaSVPHdFDdulVE. tony@​mars​:\~$ perl -le 'print crypt("longtext01"\, q($1$abcdef))' $1$abcdef$GhOCDDPkUJh7XZksRaQSH/

but you need the right magic at the front of the salt (1 is MD5)\, check your crypt man page to see what your implementation supports.

Not a bug.

Tony

p5pRT commented 13 years ago

From @ilmari

Renee BĂ€cker (via RT) \perlbug\-followup@​perl\.org writes​:

Hi\,

Shouldn't crypt produce different results for different input? [...] C​:\Users\Entwicklung>perl -le "print crypt 'longtex'\, 'BR'" BRepwQxfejBos C​:\Users\Entwicklung>perl -le "print crypt 'longtext'\, 'BR'" BRjuHtYRmCGCc C​:\Users\Entwicklung>perl -le "print crypt 'longtext0'\, 'BR'" BRjuHtYRmCGCc

From perldoc​: crypt PLAINTEXT\,SALT [...] Small changes in the PLAINTEXT or SALT will result in large changes in the digest.

Ditto​:

  Creates a digest string exactly like the crypt(3) function in the C   library

  [...]

  Traditionally [...] only the first eight bytes of PLAINTEXT   mattered.

See the crypt(3) manual page for how to choose an algorithm that takes the entire password into account.

-- ilmari "A disappointingly low fraction of the human race is\, at any given time\, on fire." - Stig Sandbeck Mathisen

p5pRT commented 13 years ago

From @wchristian

On Wed\, 13 Apr 2011 12​:59​:33 +0200\, Zefram \zefram@​fysh\.org wrote​:

Renee B??cker wrote​:

Shouldn't crypt produce different results for different input?

If it were a good algorithm then yes. But crypt() is specifically the algorithm historically used under that name in Unix\, and one of its features is that it only looks at the first eight bytes of the password. The output you're seeing is correct.

If you're building a new system\, rather than requiring compatibility with the historical crypt()\, you should use a modern hashing scheme. Here's what I wrote about crypt() in the documentation for its implementation in my Authen​::Passphrase suite (Authen​::Passphrase​::DESCrypt)​:

   Warning​: this password scheme is weak by modern standards\, and in any
   case does not support a large password space\.  Cracking crypt\(\)ed
   passwords has been a routine activity since the early 1990s\.  This
   scheme is supported for compatibility reasons only\, and should not be
   used except when compatibility is required\.  Do not use this in the
   design of any new system or for new passwords in any system that
   supports better passphrase schemes\.

I generally recommend using salted SHA-1 in new systems\, as implemented by Authen​::Passphrase​::SaltedDigest. That recommendation will change when the SHA-3 process finishes.

-zefram

IF you are using a salt to encrypt your passwords\, you want to stay away from SHA* as well\, since it's too fast. The last i heard bcrypt is the best password encryption algorithm right now​: http​://codahale.com/how-to-safely-store-a-password/

-- With regards\, Christian Walde

p5pRT commented 13 years ago

From zefram@fysh.org

Christian Walde wrote​:

you want to stay away from SHA* as well\, since it's too fast.

That's a respectable position\, but really only determinative if you're using something close to real words for your passwords\, meaning that you're especially vulnerable to dictionary attacks.

The last i heard bcrypt is the best password encryption algorithm right now

It's the only widely-deployed one with the work factor feature\, which is a good reason to choose it. Nice way to use what is otherwise a flaw in the underlying block cipher (its expensive key schedule). I'd really like to see a standardised construction for password hashing with a work factor that can be applied to an arbitrary cipher or hash function.

In a Perl context\, find bcrypt() in Crypt​::Eksblowfish​::Bcrypt or Authen​::Passphrase​::BlowfishCrypt (yes\, they're both mine). The latter has a doc paragraph commenting on the security issues.

-zefram

p5pRT commented 13 years ago

@cpansprout - Status changed from 'open' to 'rejected'