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

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

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

什么是盐?为什么需求盐?

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

把暗码幻想成一盘菜,盐便是调料,不加调料便是原汁原味的菜,调料加多加少,菜口味就不相同了

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

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

这儿用随机数来举例:

  1. 界说一个字符串,里边包含了所有或许的字符
  2. 根据传入的长度,生成一个切片,并用随机数填充
  3. 遍历这个切片,取出随机数,然后对字符串长度取余,得到一个索引,然后把这个索引对应的字符,放到切片中
  4. 返回这个切片(这个切片便是盐)
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")

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