#50996 [NEW]: crypt function incorrectly describes how to use MD5/Blowfish
| From: | cscott at ggot dot org | Date: | Wed, 10 Feb 2010 17:26:41 +0000 |
| Subject: | #50996 [NEW]: crypt function incorrectly describes how to use MD5/Blowfish | ||
| Groups: | php.doc.bugs | ||
| Request: | Send a blank email to doc-bugs+get-3860@lists.php.net to get a copy of this message | ||
From: cscott at ggot dot org
Operating system: Irrelevant
PHP version: 5.3.1
PHP Bug Type: Documentation problem
Bug description: crypt function incorrectly describes how to use MD5/Blowfish
Description:
------------
The documentation provided at http://php.net/crypt is extremely
weak
and sometimes inaccurate. At the bottom there is a note to check your
Unix man pages for more info, which would probably have been a
perfectly acceptable response, were it not for the face that PHP added
support for certain algorithms even if they were not present in the
system's library, making this a universal PHP issue now instead of
just a system/dependency issue.
I suggest the following (or something like it) be added to the PHP
Manual with respect to the crypt function in order to make this
valuable function and the changes made to its support more accessible.
Additional text that applies to all, and is implied but not made
clear:
----
Since all salts are considered to have a fixed, maximum length, the
result of a call to crypt() may be passed to subsequent calls to
crypt() in the salt parameter as a method of ensuring the same salt is
used for validation purposes. Example:
crypt(p, crypt(p, s)) == crypt(p, s)
----
Current, Erroneous (or at least misleading) text:
----
CRYPT_MD5 - MD5 encryption with a twelve character salt starting with
$1$
CRYPT_BLOWFISH - Blowfish encryption with a sixteen character salt
starting with $2$ or $2a$
At least on Windows systems, which probably means we're using the
built in PHP support for these two algorithms, they follow these
rules:
CRYPT_MD5 - The salt follows this convention: '$1$SALTsalt$'; only the
first 8 characters of any given salt will be considered, so hashes
produced with the salt '$1$SALTsalt$' will be identical to ones
produced with a salt such as '$1$SALTsaltSALTsalt$'. [[Note: I
originally thought this was because the string was being treated as a
base64 entity with a custom alphabet, but testing reveals that any
characters are valid in the salt of this algorithm]]
CRYPT_BLOWFISH - Salts are interpreted as, and hashes returned as, a
base64 string; this string is based on the GNU C Library's base64
alphabet for crypt (found here:
http://www.gnu.org/s/libc/manual/html_node/crypt.html)
but otherwise
follows standard conventions of any base64 string. The '$' character
is considered a null, or padding character.
The salt follows this convention '$2a$##$SALTsaltSALTsaltSALTsa'; The
beginning may of course be '$2$' or '$2a$'. The next three characters
should be a decimal number indicating how many times the key should be
calculated (i.e., how expensive it is to calculate the key). This
number will be interpreted as a power of two (e.g., $2a$07$ would be
interpreted as 2^7), and cannot be less than 3 or greater than 31
[[Note: have not tested this on a 64-bit system, so it might be
higher]].
The salt is composed of up to 22 characters from an alphabet ./0-9A-
Za-z with the $ symbol considered a null/end-of-string character.
Salts longer than 22 characters will only have the first 22 characters
of the salt considered, while salts shorter than 22 characters will be
padded with the '$' character, though this has no effect.
Additionally, any part of the salt following a '$' character will not
be considered (as processing of the salt will have terminated upon
first encounter of '$'). Any characters which are not a part of the
above alphabet and occur before a string-termination character ('$')
will cause crypt to fail, returning and empty string.
WARNING:{
Because the salt is interpreted as a base64 number, certain salts may
potentially produce identical results. This occurs when two salts are
identical except for one character the second salt that does not exist
in the first (e.g., 'abcd' and 'abcde'), and the shorter of the two
has a length divisible evenly by 4 (that is, Length Modulo 4 == 0).
This happens because a base64 string is interpreted 4 bytes at a time,
each byte representing 6 bits in the target string, and meaning that 1
byte requires at least two base64 characters to represent it. Because
of this, the last character will not be interpreted as part of the
salt, causing the identical hashes to be produced.
In general, you should never use a salt that is shorter than the
maximum allowed.
}
----
--
Edit bug report at http://bugs.php.net/?id=50996&edit=1
--
Try a snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=50996&r=trysnapshot52
Try a snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=50996&r=trysnapshot53
Try a snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=50996&r=trysnapshot60
Fixed in SVN: http://bugs.php.net/fix.php?id=50996&r=fixed
Fixed in SVN and need be documented: http://bugs.php.net/fix.php?id=50996&r=needdocs
Fixed in release: http://bugs.php.net/fix.php?id=50996&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=50996&r=needtrace
Need Reproduce Script: http://bugs.php.net/fix.php?id=50996&r=needscript
Try newer version: http://bugs.php.net/fix.php?id=50996&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=50996&r=support
Expected behavior: http://bugs.php.net/fix.php?id=50996&r=notwrong
Not enough info: http://bugs.php.net/fix.php?id=50996&r=notenoughinfo
Submitted twice: http://bugs.php.net/fix.php?id=50996&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=50996&r=globals
PHP 4 support discontinued: http://bugs.php.net/fix.php?id=50996&r=php4
Daylight Savings: http://bugs.php.net/fix.php?id=50996&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=50996&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=50996&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=50996&r=float
No Zend Extensions: http://bugs.php.net/fix.php?id=50996&r=nozend
MySQL Configuration Error: http://bugs.php.net/fix.php?id=50996&r=mysqlcfg