数据库在存储暗码时,不能明文存储,需求加密后存储
加密算法有很多种,比如:对称加密,非对称加密,哈希算法,暗码派生等
在加密之前,我们需求生成一些随机数,这些随机数称为盐
什么是盐?为什么需求盐?
盐是一种加密算法中的一种参数,它是一个随机数,用于增加破解暗码的难度
把暗码幻想成一盘菜,盐便是调料,不加调料便是原汁原味的菜,调料加多加少,菜口味就不相同了
也便是说,盐的多少,会影响到加密后的成果,如果不运用盐,那么相同的暗码,加密后的成果是相同的,这样就很容易被破解
盐的生成方式有很多种,比如:随机数,时间戳等
这儿用随机数来举例:
- 界说一个字符串,里边包含了所有或许的字符
- 根据传入的长度,生成一个切片,并用随机数填充
- 遍历这个切片,取出随机数,然后对字符串长度取余,得到一个索引,然后把这个索引对应的字符,放到切片中
- 返回这个切片(这个切片便是盐)
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")
这样在验证暗码时,就可以经过这些参数,把用户输入的暗码,加密后,再和数据库中存储的暗码进行比较,如果相同,就阐明暗码正确