как я уже говорил, моя функция rand представляет собой модифицированную версию функции crypt_random из phpseclib. Вы могли видеть это по ссылке, указанной в моем первом посте. по крайней мере это подтвердил автор криптографической библиотеки phpseclib; недостаточно для обычных приложений? я не говорю об экстремальной/теоретической безопасности, просто говорю о практической безопасности в той мере, в какой это действительно необходимо, и в то же время «легко»/«достаточно дешево», доступной почти для всех обычных приложений в Интернете.
crypt_random в phpseclib эффективно и незаметно возвращается к mt_rand (который, как вы должны знать, действительно слаб) в худшем случае (отсутствуют openssl_random_pseudo_bytes или urandom), но моя функция использует гораздо более безопасную схему в таких случаях. это просто откат к схеме, в которой перебор/предсказание его вывода намного сложнее и (должно быть) на практике достаточным для всех обычных приложений/сайтов. он использует возможную (на практике очень вероятную и трудно предсказуемую/обойденную) дополнительную энтропию, которая накапливается с течением времени, и которая быстро становится почти невозможной для посторонних. он добавляет эту возможную энтропию к выводу mt_rand (а также к выводу других источников: urandom, openssl_random_pseudo_bytes, mcrypt_create_iv). если вы проинформированы, вы должны знать, что эта энтропия может быть добавлена, но не вычтена. в (почти наверняка очень редком) худшем случае эта дополнительная энтропия будет равна 0 или слишком малой величине. в посредственном случае, который я думаю почти во всех случаях, это было бы даже больше, чем практически необходимо, я думаю. (у меня были обширные исследования в области криптографии, поэтому, когда я говорю, что думаю, это основано на гораздо более информированном и научном анализе, чем у обычных программистов).
см. полный код моего модифицированного crypt_random:
function crypt_random($min = 0, $max = 0x7FFFFFFF)
{
if ($min == $max) {
return $min;
}
global $entropy;
if (function_exists('openssl_random_pseudo_bytes')) {
// openssl_random_pseudo_bytes() is slow on windows per the following:
// http://stackoverflow.com/questions/1940168/openssl-random-pseudo-bytes-is-slow-php
if ((PHP_OS & "\xDF\xDF\xDF") !== 'WIN') { // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
extract(unpack('Nrandom', pack('H*', sha1(openssl_random_pseudo_bytes(4).$entropy.microtime()))));
return abs($random) % ($max - $min) + $min;
}
}
// see http://en.wikipedia.org/wiki//dev/random
static $urandom = true;
if ($urandom === true) {
// Warning's will be output unles the error suppression operator is used. Errors such as
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
$urandom = @fopen('/dev/urandom', 'rb');
}
if (!is_bool($urandom)) {
extract(unpack('Nrandom', pack('H*', sha1(fread($urandom, 4).$entropy.microtime()))));
// say $min = 0 and $max = 3. if we didn't do abs() then we could have stuff like this:
// -4 % 3 + 0 = -1, even though -1 < $min
return abs($random) % ($max - $min) + $min;
}
if(function_exists('mcrypt_create_iv') and version_compare(PHP_VERSION, '5.3.0', '>=')) {
@$tmp16=mcrypt_create_iv(4, MCRYPT_DEV_URANDOM);
if($tmp16!==false) {
extract(unpack('Nrandom', pack('H*', sha1($tmp16.$entropy.microtime()))));
return abs($random) % ($max - $min) + $min;
}
}
/* Prior to PHP 4.2.0, mt_srand() had to be called before mt_rand() could be called.
Prior to PHP 5.2.6, mt_rand()'s automatic seeding was subpar, as elaborated here:
http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/
The seeding routine is pretty much ripped from PHP's own internal GENERATE_SEED() macro:
http://svn.php.net/viewvc/php/php-src/tags/php_5_3_2/ext/standard/php_rand.h?view=markup */
static $seeded;
if (!isset($seeded) and version_compare(PHP_VERSION, '5.2.5', '<=')) {
$seeded = true;
mt_srand(fmod(time() * getmypid(), 0x7FFFFFFF) ^ fmod(1000000 * lcg_value(), 0x7FFFFFFF));
}
extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF).$entropy.microtime()))));
return abs($random) % ($max - $min) + $min;
}
$entropy содержит мою дополнительную энтропию, которая получается из энтропии всех параметров запросов, объединенной до сих пор + энтропии параметров текущего запроса + энтропии случайной строки (*), заданной вручную во время установки.
*: длина: 22, состоит из строчных и прописных букв + цифр (более 128 бит энтропии)
person
H M
schedule
10.04.2012
update
crypto` setvalue
=sha1(concat(value
, DATE()))) где name='entropy'`. Это происходит потому, что SHA1 (разработанный как) является спорным. - person Mark Huk   schedule 27.03.2012