好吧,看看这个错误,它似乎确实是一个问题。
深入研究源代码,这一行是使它起作用的原因:
srand(Configure::read('Security.cipherSeed'));
现在,为什么会这样?因为rand()
实现了伪随机算法。所以对于任何给定的已知种子,理论上你可以产生同一系列的随机输出。为了看看这是否可行,让我们看看PHP 源代码rand()
,特别是内部php_rand
函数:
PHPAPI long php_rand(TSRMLS_D)
{
long ret;
if (!BG(rand_is_seeded)) {
php_srand(GENERATE_SEED() TSRMLS_CC);
}
我们知道这不是问题,因为我们是手动播种(除非我们在服务器上安装了 suhosin 补丁,否则它将始终重新播种,因此无法正常工作)。
#ifdef ZTS
ret = php_rand_r(&BG(rand_seed));
#else
# if defined(HAVE_RANDOM)
ret = random();
# elif defined(HAVE_LRAND48)
ret = lrand48();
# else
ret = rand();
# endif
#endif
哇,你看到发生了什么吗?根据服务器规范,可以使用 4 个不同的随机库之一(rand()
, random()
,lrand48()
或者它自己的内部随机函数php_rand_r
)!这就是为什么它不能跨服务器安装移植。
相反,请使用真正的加密库,例如MCrypt或GPG。
编辑:我已经向cake 提交了关于这个主题的错误报告。