[PATCH perlfunc.pod/crypt] crypt() digests, not encrypts
Michael G. Schwern [Sat, 23 Jul 2005 17:25:18 +0000 (10:25 -0700)]
Date: Sat, 23 Jul 2005 17:25:18 -0700
Message-ID: <20050724002518.GB4918@windhund.schwern.org>

Subject: Re: [PATCH perlfunc.pod/crypt] crypt() digests, not encrypts
From: Michael G Schwern <schwern@pobox.com>
Date: Sun, 24 Jul 2005 13:49:25 -0700
Message-ID: <20050724204925.GC13275@windhund.schwern.org>

p4raw-id: //depot/perl@25220

pod/perlfunc.pod

index 43dc07b..761bd3a 100644 (file)
@@ -885,31 +885,42 @@ function, or use this relation:
 
 =item crypt PLAINTEXT,SALT
 
-Encrypts a string exactly like the crypt(3) function in the C library
-(assuming that you actually have a version there that has not been
-extirpated as a potential munition).  This can prove useful for checking
-the password file for lousy passwords, amongst other things.  Only the
-guys wearing white hats should do this.
-
-Note that L<crypt|/crypt> is intended to be a one-way function, much like
-breaking eggs to make an omelette.  There is no (known) corresponding
-decrypt function (in other words, the crypt() is a one-way hash
-function).  As a result, this function isn't all that useful for
-cryptography.  (For that, see your nearby CPAN mirror.)
-
-When verifying an existing encrypted string you should use the
-encrypted text as the salt (like C<crypt($plain, $crypted) eq
-$crypted>).  This allows your code to work with the standard L<crypt|/crypt>
-and with more exotic implementations.  In other words, do not assume
-anything about the returned string itself, or how many bytes in
-the encrypted string matter.
+Creates a digest string exactly like the crypt(3) function in the C
+library (assuming that you actually have a version there that has not
+been extirpated as a potential munition).
+
+crypt() is a one-way hash function.  The PLAINTEXT and SALT is turned
+into a short string, called a digest, which is returned.  The same
+PLAINTEXT and SALT will always return the same string, but there is no
+(known) way to get the original PLAINTEXT from the hash.  Small
+changes in the PLAINTEXT or SALT will result in large changes in the
+digest.
+
+There is no decrypt function.  This function isn't all that useful for
+cryptography (for that, look for F<Crypt> modules on your nearby CPAN
+mirror) and the name "crypt" is a bit of a misnomer.  Instead it is
+primarily used to check if two pieces of text are the same without
+having to transmit or store the text itself.  An example is checking
+if a correct password is given.  The digest of the password is stored,
+not the password itself.  The user types in a password which is
+crypt()'d with the same salt as the stored digest.  If the two digests
+match the password is correct.
+
+When verifying an existing digest string you should use the digest as
+the salt (like C<crypt($plain, $digest) eq $digest>).  The SALT used
+to create the digest is visible as part of the digest so this ensures
+crypt() will hash the new string with the same salt as the digest.
+This allows your code to work with the standard L<crypt|/crypt> and
+with more exotic implementations.  In other words, do not assume
+anything about the returned string itself, or how many bytes in the
+digest matter.
 
 Traditionally the result is a string of 13 bytes: two first bytes of
 the salt, followed by 11 bytes from the set C<[./0-9A-Za-z]>, and only
-the first eight bytes of the encrypted string mattered, but
-alternative hashing schemes (like MD5), higher level security schemes
-(like C2), and implementations on non-UNIX platforms may produce
-different strings.
+the first eight bytes of the digest string mattered, but alternative
+hashing schemes (like MD5), higher level security schemes (like C2),
+and implementations on non-UNIX platforms may produce different
+strings.
 
 When choosing a new salt create a random two character string whose
 characters come from the set C<[./0-9A-Za-z]> (like C<join '', ('.',
@@ -938,11 +949,9 @@ their own password:
 Of course, typing in your own password to whoever asks you
 for it is unwise.
 
-The L<crypt|/crypt> function is unsuitable for encrypting large quantities
+The L<crypt|/crypt> function is unsuitable for hashing large quantities
 of data, not least of all because you can't get the information
-back.  Look at the F<by-module/Crypt> and F<by-module/PGP> directories
-on your favorite CPAN mirror for a slew of potentially useful
-modules.
+back.  Look at the L<Digest> module for more robust algorithms.
 
 If using crypt() on a Unicode string (which I<potentially> has
 characters with codepoints above 255), Perl tries to make sense