有关MD5与Bcript的battle

417 阅读4分钟

有关MD5与Bcript的battle | 青训营笔记

这是我参与「第五届青训营 」伴学笔记创作活动的第 N 天

在开发抖音项目过程中登录注册模块需要使用密码加密功能,于是对加密方面进行了学习。

引言

MD5是加密算法吗?

这里有很多同学有个误区,认为MD5是加密算法,其实这是不对的。

从概念上来说『加密』对应的是『解密』,我们把数据采用某种方式加密之后,可以在之后的某一时刻进行解密来获得原始数据,这才是加密算法。

MD5 是一种哈希算法,又叫散列算法或者摘要算法,是一类把任意长度数据转换为定长数据的算法统称,它广泛应用于错误检查,经常通过计算 MD5 来检验下载到的文件的完整性,优秀的哈希算法通常需要具有低碰撞概率,MD5 就是其中的一种。

img

介绍

常见的加密工具有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之后得到的总是相同的,用一个字符串计算出来的哈希值也是固定的,所以出现了一些针对该算法的破解方法。

  1. 暴力枚举法:因为可以不断尝试,并且随着计算机硬件能力的快速提升,使得这种方法来破解短密码称为了可能
  2. 字典法:也就是撞库,黑客通过收集互联网已泄露的用户和密码信息,生成对应的字典表,通过撞库来完成破解
  3. 彩虹表:在字典法的基础上改进,以时间换空间,使用预计算的哈希链集来降低存储空间,是目前最常用的方法

常见的优化方法有加上随机盐,但是还得存储这些盐,一般是存在数据库中,但是数据库也存在泄漏风险,这样盐也泄漏了,又存在安全隐患。

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
}