使用Golang保存密码
作为密码保存方法,
一般来说,将明文密码经过单向哈希加密后保存是常见的做法。
在哈希算法中,有SHA-256、SHA-1、MD5等几种选项。
使用Golang,可以通过crypto包轻松实现。
以下是使用SHA256进行实现的示例。
//import "crypto/sha256"
h := sha256.New()
io.WriteString(h, "my password")
fmt.Printf("% x", h.Sum(nil))
更好的方法 de
通常情况下,由于在加密过程中使用了以上公开的哈希算法,再加上计算机计算能力的提升和技术的进步,黑客通过使用彩虹表解密上述方法中哈希过的密码已经变得不再困难(时间上)。
彩虹表:存储了哈希结果(摘要)的数据库。
在中国,一种直接的解决方法是自己设计一个哈希算法。
然而,设计出优秀的哈希算法非常困难。
因此,在實際的應用中,會使用現有的哈希算法進行多次哈希處理。
然而,对于简单的多次哈希,黑客们也会自然而然地想到。
因此,管理员会添加一个仅管理员自己知道的随机字符串,并再次进行哈希处理。
用盐(salt)来指称那个随机字符串。就像在料理中撒上一抹盐一样,一下子能够增加食物的美味程度,通过哈希来破解密码的难度也会大大提升。
//import "crypto/md5"
h := md5.New()
io.WriteString(h, "your password")
pw_md5 :=fmt.Sprintf("%x", h.Sum(nil))
//saltを指定します
salt := "your salt"
//salt1+ユーザ名+salt2+MD5を連結します。
io.WriteString(h, salt)
//io.WriteString(h, "username") // ユーザ名を連結しても良い
//io.WriteString(h, salt2) // saltは複数かけても良い
io.WriteString(h, pw_md5)
result :=fmt.Sprintf("%x", h.Sum(nil))
如果没有盐泄漏,即使黑客获得了加密字符串,也几乎不可能猜测出原始密码是什么。
更安全的方法 de
然而,随着并行计算能力的提高,只要有足够的资源来创建彩虹表,这种攻击已经完全有可能。
因此,可以通过故意增加计算密码所需的资源和时间,以防止任何人创建彩虹表所需的资源。
通过调整算法的因子(参数),可以提高计算强度来实现这种方法。
在Golang中,已经提供了一个名为scrypt的库,以下是这个库的示例。
package main
import (
"encoding/base64"
"fmt"
"log"
"golang.org/x/crypto/scrypt"
)
func main() {
password = "your password"
// saltはご自身のものに入れ替えてください
salt := "your salt"
dk, err := scrypt.Key([]byte(password), []byte(salt), 1<<15, 8, 1, 32)
if err != nil {
log.Fatal(err)
}
fmt.Println(base64.StdEncoding.EncodeToString(dk))
}
这里有一篇论文详细介绍了scrypt的内容。
请参考下面的文章。
使用Golang构建网络应用程序
PHP:安全的密码哈希
原文: 元記事
Paraphrase: 文章的起始部分
用Golang保存密码