加密

加密

一直以来,用的密码是md5或者sha1等单向加密函数,为了提高密码的强度,有时候可能会加盐。但是第一次听说<>加密算法,自动生成盐。

PHP

BCRYPT加密算法,对应php的算法如下。

password_hash

//加密
$options = [
    'cost' => 10,
];
$hash = password_hash('chaofml', PASSWORD_BCRYPT ,$options);
echo $hash."\n";
//解密
var_dump(   password_verify('chaofml',$hash) );

产生的密码类似于:

$2y$10$iGZTT9F6dUHVbRCYWtQG7OBJTQEqu6klcLiup7ejVVI.JV4GfbZJW

关于格式的解读:

  • 同一个密码,每次生成的hash都是不一样的。
  • 既然每次hash都不一样,那么如何判断加密是否正确呢?
    是这样的:在加密的时候,先随机获取salt,然后跟password进行hash。在下一次校验的时候,从hash中取出salt,salt跟password进行hash,得到的结果跟保存在在数据库的hash进行比较。
  • 生成的密码中,$是分割符,无意义;2a是bcrypt加密版本号;10是cost的值(默认值);而后的前22位是salt值;再然后的字符串就是密码的密文了
  • BCrypt是单向的,而且经过salt和cost的处理,使其受rainbow攻击破解的概率大大降低,同时破解的难度也提升不少
  • 加盐:如果两个人或多个人的密码相同,加密后保存会得到相同的结果。破一个就可以破一片的密码。如果名为A的用户可以查看数据库,那么他可以观察到自己的密码和别人的密码加密后的结果都是一样,那么,别人用的和自己就是同一个密码,这样,就可以利用别人的身份登录了。其实只要稍微混淆一下就能防范住了,这在加密术语中称为“加盐”。具体来说就是在原有材料(用户自定义密码)中加入其它成分(一般是用户自有且不变的因素),以此来增加系统复杂度。当这种盐和用户密码相结合后,再通过摘要处理,就能得到隐蔽性更强的摘要值。

参见这个链接:

https://blog.csdn.net/x2hg123/article/details/107961008

为啥是2y开头而不是2a开头呢?

见:

https://www.v2ex.com/t/218183

这个里面也有说明: https://www.php.net/manual/en/function.crypt.php

大概是默认的2a太弱了,有安全漏洞,所以至php5.3以上版本,已经修改了。

mysql

MYSQL的基本函数 (加密函数)
AES_ENCRYPT(str,key)

返回用密钥key对字符串str利用高级加密标准算法加密后的结果,调用AES_ENCRYPT的结果是一个二进制字符串,以BLOB类型存储
AES_DECRYPT(str,key) 返回用密钥key对字符串str利用高级加密标准算法解密后的结果
DECODE(str,key) 使用key作为密钥解密加密字符串str
ENCRYPT(str,salt) 使用UNIXcrypt()函数,用关键词salt(一个可以惟一确定口令的字符串,就像钥匙一样)加密字符串str
ENCODE(str,key) 使用key作为密钥加密字符串str,调用ENCODE()的结果是一个二进制字符串,它以BLOB类型存储
MD5() 计算字符串str的MD5校验和
PASSWORD(str) 返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。
SHA() 计算字符串str的安全散列算法(SHA)校验和
示例:
SELECT ENCRYPT(‘root’,’salt’);
SELECT ENCODE(‘xufeng’,’key’);
SELECT DECODE(ENCODE(‘xufeng’,’key’),’key’);#加解密放在一起
SELECT AES_ENCRYPT(‘root’,’key’);
SELECT AES_DECRYPT(AES_ENCRYPT(‘root’,’key’),’key’);
SELECT MD5(‘123456’);
SELECT SHA(‘123456’);