php md5还原原来,在PHP中更新旧的存储的md5密码以提高安全性

好的,我们在这里讨论几点

>你在$salt中所拥有的不是盐.这是确定性的(意味着根本就没有随机性).如果您想要盐,请使用mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)或其他一些实际随机熵源.关键是它应该既独特又随意.请注意,它不需要加密安全随机…在绝对最差的情况下,我会做这样的事情:

function getRandomBytes($length) {

$bytes = '';

for ($i = 0; $i < $length; $i++) {

$bytes .= chr(mt_rand(0, 255));

}

return $bytes;

}

>正如@ Anony-Mousse指出的那样,从不将一个哈希函数的输出提供给另一个哈希函数而不将原始数据重新附加到它.相反,使用适当的迭代算法,如PBKDF2,PHPASS或CRYPT_BLOWFISH($2a $).

我的建议是使用带有河豚的crypt,因为它是目前PHP最好的:

function createBlowfishHash($password) {

$salt = to64(getRandomBytes(16));

$salt = '$2a$10$' . $salt;

$result = crypt($password, $salt);

}

然后使用如下方法验证:

function verifyBlowfishHash($password, $hash) {

return $hash == crypt($password, $hash);

}

(注意,to64是定义here的好方法).你也可以使用str_replace(”,’.’,base64_encode($salt)); …

我还建议你阅读以下两点:

编辑:回答迁移问题

好的,所以我意识到我的答案没有解决原始问题的迁移方面.所以这就是我如何解决它.

首先,构建一个临时函数,从原始的md5哈希创建一个新的河豚哈希,带有随机盐和前缀,以便我们以后可以检测到:

function migrateMD5Password($md5Hash) {

$salt = to64(getRandomBytes(16));

$salt = '$2a$10$' . $salt;

$hash = crypt($md5Hash, $salt);

return '$md5' . $hash;

}

现在,通过此函数运行所有现有的md5哈希,并将结果保存在数据库中.我们将自己的前缀放入,以便我们可以检测原始密码并添加额外的md5步骤.所以现在我们都迁移了.

接下来,创建另一个函数来验证密码,如果需要,使用新的哈希更新数据库:

function checkAndMigrateHash($password, $hash) {

if (substr($hash, 0, 4) == '$md5') {

// Migrate!

$hash = substr($hash, 4);

if (!verifyBlowfishHash(md5($password), $hash) {

return false;

}

// valid hash, so let's generate a new one

$newHash = createBlowfishHash($password);

saveUpdatedPasswordHash($newHash);

return true;

} else {

return verifyBlowfishHash($password, $hash);

}

}

这是我建议的原因有几点:

>它立即从数据库中获取md5()哈希值.

>它最终(每个用户的下一次登录)将哈希更新为更好的替代方案(一个很好理解的方法).

>在代码中很容易理解.

回答评论:

If there is no concern about interactions between multiple uses

of the same key (or a prefix of that key) with the password-

based encryption and authentication techniques supported for a

given password, then the salt may be generated at random and

need not be checked for a particular format by the party

receiving the salt. It should be at least eight octets (64

bits) long.

另外,

Note. If a random number generator or pseudorandom generator is not

available, a deterministic alternative for generating the salt (or

the random part of it) is to apply a password-based key derivation

function to the password and the message M to be processed.

可以使用伪随机生成器,为什么不使用它呢?

>您的解决方案与bcrypt相同吗?我找不到关于bcrypt究竟是什么的文档? – 我假设您已经阅读了bcrypt Wikipedia Article,并尝试更好地解释它.

BCrypt基于Blowfish分组密码.它从密码中获取密钥调度设置算法,并使用它来散列密码.好的原因是,Blowfish的设置算法设计得非常昂贵(这是使河豚如此强大的一部分的一部分).基本流程如下:

> 18个元素阵列(称为P盒,大小为32位)和4个2维阵列(称为S盒,每个具有256个条目,每个8位)用于通过使用预定静态值初始化阵列来设置调度.另外,64位状态被初始化为全0.

>传入的密钥是按顺序XOred所有18个P盒(如果它太短则旋转键).

>然后使用P框加密先前初始化的状态.

>步骤3产生的密文用于替换P1和P2(P阵列的前2个元素).

>重复步骤3,将结果放入P3和P4.这一直持续到P17和P18填充.

这是Blowfish Cipher的关键衍生物. BCrypt修改了这个:

> 64位状态初始化为盐的加密版本.

>相同

>然后使用P框加密先前初始化的(状态x或部分盐).

>相同

>相同

>然后,生成的设置用于加密密码64次.这就是BCrypt所回归的.

重点很简单:这是一个非常昂贵的算法,占用了大量的CPU时间.这是它应该被使用的真正原因.

我希望能够解决问题.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值