有关MD5与Bcript的battle | 青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 N 天
在开发抖音项目过程中登录注册模块需要使用密码加密功能,于是对加密方面进行了学习。
引言
MD5是加密算法吗?
这里有很多同学有个误区,认为MD5是加密算法,其实这是不对的。
从概念上来说『加密』对应的是『解密』,我们把数据采用某种方式加密之后,可以在之后的某一时刻进行解密来获得原始数据,这才是加密算法。
MD5是一种哈希算法,又叫散列算法或者摘要算法,是一类把任意长度数据转换为定长数据的算法统称,它广泛应用于错误检查,经常通过计算MD5来检验下载到的文件的完整性,优秀的哈希算法通常需要具有低碰撞概率,MD5就是其中的一种。
介绍
常见的加密工具有MD5,Bcrypt等。
MD5:是不加盐的单向Hash,不可逆的加密算法,同一个密码经过hash的时候生成的是同一个hash值,在大多数的情况下,有些经过md5加密的方法将会被破解。
Bcrypt:一种加盐的单向Hash,不可逆的加密算法,同一种明文(plaintext),每次加密后的密文都不一样,而且不可反向破解生成明文,破解难度很大。
Bcrypt生成的密文是60位的。而MD5的是32位的。
目前,MD5和BCrypt比较流行。相对来说,BCrypt比MD5更安全,但加密更慢。 虽然BCrpyt也是输入的字符串+盐,但是与MD5+盐的主要区别是:每次加的盐不同,导致每次生成的结果也不相同。无法比对!
安全性比较
Bcript > MD5
MD5不太安全
因为MD5算法是确定的,同一个字符串经过MD5之后得到的总是相同的,用一个字符串计算出来的哈希值也是固定的,所以出现了一些针对该算法的破解方法。
- 暴力枚举法:因为可以不断尝试,并且随着计算机硬件能力的快速提升,使得这种方法来破解短密码称为了可能
- 字典法:也就是撞库,黑客通过收集互联网已泄露的用户和密码信息,生成对应的字典表,通过撞库来完成破解
- 彩虹表:在字典法的基础上改进,以时间换空间,使用预计算的哈希链集来降低存储空间,是目前最常用的方法
常见的优化方法有加上随机盐,但是还得存储这些盐,一般是存在数据库中,但是数据库也存在泄漏风险,这样盐也泄漏了,又存在安全隐患。
BCrypt更加安全
自己加盐
BCrypt内部自己实现了随机加盐处理,可以实现每次加密后的密文是不一样的。也就是每次生成的Hash结果是不一样的,MD5每次是相同的。
生成的Hash值通常格式如下:
$2b$12$ABJPtagiuqTVhnIPvOLoB.hbIlZ3joRkpck3joDsX6xe3O2KShuty
那你就知道了加密版本、工作负载,盐的信息,这样会不会很危险呢?
工作负载
BCrypt的工作负载有时也称为加密轮数、成本因子等等(一提到工作负载就想到比特币,数字游戏而已),目的就是提高破解难度,带来的缺点就是速度慢。MD5的Hash值生成通常是微妙级别的,但是Bcrypt一个密码出来的时间比较长。
当我们将验证用户密码的成本提高几个数量级时,攻击者的成本其实也相应的提升了几个数量级,只要我们让攻击者的攻击成本大于硬件的限制,同时保证正常请求的耗时在合理范围内,我们就能够保证用户密码的相对安全。
GO语言中使用
安装
go get golang.org/x/crypto/bcrypt
加密与验证
// HashPassword 使用bcrypt算法返回hash后密码
func HashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
// CheckPasswordHash 检查密码是否相等
func CheckPasswordHash(password string, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}