我正在学习PHP的crypt()函数,并且一直在运行一些测试。根据this post,我应该使用22个字符长的盐。但是,我可以使用长度为23个字符的字符串,但有一些限制。当我使用长度为22个字符的字符串时,我总是得到'$ 2y $ xxStringStringStringStri.HashHashHashHashHashHashHashHas'的结果。我知道这个时期只是盐的一部分。为什么我不应该在crypt()函数的盐中使用第23个字符?
看来,如果我使用23个字符而不是22个字符,我可以成功生成不同的哈希值,但对于所有64个字符只有4种不同的结果。第23位字符“向下取整”到64个字符的字母的最接近的1/4(例如第23位字符是“W”和向下取整为“O”或任何数量的向下取整为“U”)
v---------------v---------------v---------------v---------------
./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890
这些隐窝功能全部四生成相同的盐:
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAq');
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAr');
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAs');
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAt');
但是这一次不同的是:
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAu');
那么,为什么我不应该使用23位字符时能够顺利产生不同的结果? PHP中是否存在某种类似的不良行为,应该通过不使用它来避免?
为了澄清,我怎么在盐计算的23位字符:
crypt('Test123','$2y$08$ABCDEFGHIJKLMNOPQRSTUV');
// The salt is '$ABCDEFGHIJKLMNOPQRSTUV'
// Which will be treated as '$ABCDEFGHIJKLMNOPQRSTUO'
关于这个问题有一个很好的解释:http://security.stackexchange.com/questions/20862/php-crypt-trims-the-salt-as-it-would-be-too-long – 2013-03-05 16:53:06
谢谢你这个回应。虽然这只能解决第23个字符所发生的情况,因为它只会因crypt()函数中允许的位的大小而缩短。另外一个问题,我的问题是“即使将它切成两位,我是否应该使用第23个字符?”或者另一种方式是“每当使用第23个字符时,PHP算法中是否会产生错误的哈希?” – Andrew 2013-03-05 17:11:22