前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >密码还在用 MD5 加盐?不如试试 Bcrypt

密码还在用 MD5 加盐?不如试试 Bcrypt

作者头像
LinkinStar
发布2024-02-09 08:53:10
3070
发布2024-02-09 08:53:10
举报
文章被收录于专栏:LinkinStar's Blog

很长一段时间我也是用 MD5 + 盐 来解决绝大多数密码的问题的,因为确实很方便。不过,从安全的角度来说,还是有风险,那就干脆直接上 Bcrypt 吧。

MD5 + salt

其实,在大多场景够用了,毕竟 hash 和 salt 同时被黑的概率太低了,不过其实 MD5 最大的问题不是到不是这个,而是算的太快了,随着计算能力的发展总会是有概率被破解的。

代码语言:javascript
复制
password_hash = md5(password+salt)

Bcrypt 的特点

  • hash 不可逆
  • 随机 salt
  • 可调整的计算 cost

上代码

不多说,直接上代码,看怎么用,然后再分析。

代码语言:javascript
复制
package main

import (
	"fmt"

	"golang.org/x/crypto/bcrypt"
)

func main() {
	password := "123456"
	fmt.Printf("第一次加密后的密码: %s\n", encryptPassword(password))
	fmt.Printf("第二次加密后的密码: %s\n", encryptPassword(password))

	fmt.Printf("密码比对结果: %v\n", comparePassword(password, encryptPassword(password)))
	fmt.Printf("密码比对结果: %v\n", comparePassword("123", encryptPassword(password)))
}

func encryptPassword(password string) string {
	hashPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		panic(err)
	}
	return string(hashPassword)
}

func comparePassword(password, hashPassword string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(hashPassword), []byte(password))
	return err == nil
}
代码语言:javascript
复制
# output

第一次加密后的密码: $2a$10$dFPckrZLstSKxX8zf3uUKurLw4Pes.G3APfrDIQfVHCFyGmUq4J7K
第二次加密后的密码: $2a$10$nYbAG/Om/bjEGq..x5TsVOy5VIVWudVaFxchrWLWPO5M7tMDIBDVO
密码比对结果: true
密码比对结果: false

golang.org/x/crypto/bcrypt 提供了 bcrypt 方法,所以使用起来非常简单的。

  • GenerateFromPassword 提供了加密(hash) 的方法,其中第二个参数是计算成本(工作因子),越大计算耗时越长 MaxCost 是 31
  • CompareHashAndPassword 提供了验证的方法,用于验证用户输入的密码是否正确

最让人安心的就是,它的每次 hash 结果都都是不一样的,原因就是每次的 salt 也是不一样的。我们知道,md5 使用相同的 字符串 前后两次 hash 是一样的,从而可以验证前后用的密码是不是一样的。那么,Bcrypt 每次的 hash 都不一样,如何它是如何做验证呢?

原理一瞥

hash 结构

首先我们看看 hash 之后的结果

代码语言:javascript
复制
$2a$10$nYbAG/Om/bjEGq..x5TsVOy5VIVWudVaFxchrWLWPO5M7tMDIBDVO
\__/\/ \____________________/\_____________________________/
 A  C      Salt                        Hash
  • A:表示 hash 的方式,2a 代表 Bcrypt 加密版本号
  • C:表示迭代次方数
  • Salt:是盐
  • Hash:是最后的值

分析

其实看完了结构你就不难猜测到它的原理了,说白了验证的方式很简单,就是将 hash 后的结果中的 Salt 取出来,然后对用户输入的密码再次使用相同的方式和次数进行 hash,然后比较结果,看结果是否一致。也就是说,其实 Bcrypt 的 hash 结果并不仅仅只是包含了 hash 还包含了具体的 hash 计算方式和 Salt。

总结

所以,Bcrypt 相比于 MD5 来说,我认为最关键的还是有了 cost 这个选项,并且本身的计算就比 MD5 的时间要长,大大的提高了破解的难度,而且由于 salt 的不固定,彩虹表是别想了。最后,还有一个关键点要提醒你:Bcrypt 的加密长度是有限制的,比如 golang 这里的库限制长度最大为 72,超过就会报错。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MD5 + salt
  • Bcrypt 的特点
  • 上代码
  • 原理一瞥
    • hash 结构
      • 分析
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档