go 密码加密的方式

2023年 7月 19日 19.3k 0

数据库在存储密码时,不能明文存储,需要加密后存储

加密算法有很多种,比如:对称加密,非对称加密,哈希算法,密码派生等

在加密之前,我们需要生成一些随机数,这些随机数称为盐

什么是盐?为什么需要盐?

盐是一种加密算法中的一种参数,它是一个随机数,用于增加破解密码的难度

把密码想象成一盘菜,盐就是调料,不加调料就是原汁原味的菜,调料加多加少,菜口味就不一样了

也就是说,盐的多少,会影响到加密后的结果,如果不使用盐,那么相同的密码,加密后的结果是一样的,这样就很容易被破解

盐的生成方式有很多种,比如:随机数,时间戳等

这里用随机数来举例:

  • 定义一个字符串,里面包含了所有可能的字符
  • 根据传入的长度,生成一个切片,并用随机数填充
  • 遍历这个切片,取出随机数,然后对字符串长度取余,得到一个索引,然后把这个索引对应的字符,放到切片中
  • 返回这个切片(这个切片就是盐)
  • func generateSalt(length int) []byte {
      const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
      salt := make([]byte, length)
      rand.Read(salt)
      for key, val := range salt {
        salt[key] = alphanum[val%byte(len(alphanum))]
      }
      return salt
    }
    

    生成盐之后,我们就可以对密码进行加密了

    加密后的密码要使用 hex.EncodeToString 转换成字符串

    salt := generateSalt(16)
    encoded := pbkdf2.Key([]byte("uccs"), salt, 100, 32, sha256.New)
    encodedPwd := hex.EncodeToString(encodedPwd)
    

    因为这个加密算法是不可逆的,也就说你不能通过加密后的密码,反推出原始密码

    那用户输入密码时,如何知道密码是否正确呢?

    所以在存储加密后的密码时,还要存储盐和加密算法的参数

    这里使用的是 pbkdf2 算法,它的参数有:原始密码,盐,迭代次数,密钥长度,哈希算法

    所以最终存在数据的密码是:

    pwd := fmt.Sprintf("%s$%s$%d$%d$%s", encodedPwd, salt, 100, 32, "pbkdf2-sha256")
    

    这样在验证密码时,就可以通过这些参数,把用户输入的密码,加密后,再和数据库中存储的密码进行比较,如果相同,就说明密码正确

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论