diff options
author | Dries Buytaert <dries@buytaert.net> | 2008-03-31 20:50:05 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2008-03-31 20:50:05 +0000 |
commit | ed59911f9ee542da87ae7cddcb2d50da0e785079 (patch) | |
tree | 8b7f873dd371ae19d1f678e26ad548c47ff1b0ad /includes | |
parent | 763298455f88e26f286749b5f7ff6c9471742012 (diff) | |
download | brdo-ed59911f9ee542da87ae7cddcb2d50da0e785079.tar.gz brdo-ed59911f9ee542da87ae7cddcb2d50da0e785079.tar.bz2 |
- Patch #29706 by pwolanin, solardiz, et al: more secure password hashing.
This is a big and important patch for Drupal's security. We are switching
to much stronger password hashes that are also compatible with the Portable
PHP password hashing framework.
The new password hashes defeat a number of attacks, including:
- The ability to try candidate passwords against multiple hashes at once.
- The ability to use pre-hashed lists of candidate passwords.
- The ability to determine whether two users have the same (or different)
password without actually having to guess one of the passwords.
Also implemented a pluggable password hashing API (similar to how an alternate
cache mechanism can be used) to allow developers to readily substitute an
alternative hashing and authentication scheme.
Thanks all!
Diffstat (limited to 'includes')
-rw-r--r-- | includes/common.inc | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/includes/common.inc b/includes/common.inc index 52d8babd8..a77479e1f 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2308,6 +2308,44 @@ function drupal_urlencode($text) { } /** + * Returns a string of highly randomized bytes (over the full 8-bit range). + * + * This function is better than simply calling mt_rand() or any other built-in + * PHP function because it can return a long string of bytes (compared to < 4 + * bytes normally from mt_rand()) and uses the best available pseudo-random source. + * + * @param $count + * The number of characters (bytes) to return in the string. + */ +function drupal_random_bytes($count) { + static $random_state; + // We initialize with the somewhat random PHP process ID on the first call. + if (empty($random_state)) { + $random_state = getmypid(); + } + $output = ''; + // /dev/urandom is available on many *nix systems and is considered the best + // commonly available pseudo-random source. + if ($fh = @fopen('/dev/urandom', 'rb')) { + $output = fread($fh, $count); + fclose($fh); + } + // If /dev/urandom is not available or returns no bytes, this loop will + // generate a good set of pseudo-random bytes on any system. + // Note that it may be important that our $random_state is passed + // through md5() prior to being rolled into $output, that the two md5() + // invocations are different, and that the extra input into the first one - + // the microtime() - is prepended rather than appended. This is to avoid + // directly leaking $random_state via the $output stream, which could + // allow for trivial prediction of further "random" numbers. + while (strlen($output) < $count) { + $random_state = md5(microtime() . mt_rand() . $random_state); + $output .= md5(mt_rand() . $random_state, TRUE); + } + return substr($output, 0, $count); +} + +/** * Ensure the private key variable used to generate tokens is set. * * @return @@ -2315,7 +2353,7 @@ function drupal_urlencode($text) { */ function drupal_get_private_key() { if (!($key = variable_get('drupal_private_key', 0))) { - $key = md5(uniqid(mt_rand(), true)) . md5(uniqid(mt_rand(), true)); + $key = md5(drupal_random_bytes(64)); variable_set('drupal_private_key', $key); } return $key; |