Go语言使用使用Bcrypt实现加密或验证密码| 青训营

561 阅读2分钟

使用Bcrypt实现加密或验证登录密码

Bcrypt 就是一款加密工具,它生成的密文是60位的,而且每次加密生成的值是不一样的。MD5 加密后的值是32位的,且每次加密后的密文都是一样的。 保存密码,一般我们都推荐使用 Bcrypt 进行加密,而不使用 MD5。 从安全上讲,用户密码一般都是要经过加密(而且不能被解密)后才存储于数据库中。

虽然MD5算法不可逆,然而每次使用MD5生成的字符串都是固定的,这就给暴力破解留下了余地。

如果使用Bcrypt算法加密,那么每次生成的字符串都是不同的,这样产生的密文基本无法破解。Java语言的spring-security 框架内置了BCryptPasswordEncoder来实现Bcrypt加密。当然Go也提供了包golang.org/x/crypto/bcrypt用来实现Bcrypt加密。

  • Bcrypt 加密后的值举例:

比如加密 admin, 两次结果不一样,但都以 $2a 开头: $2a$10$cL3WHWi3/x96MII1pwm4NOMRESxbAHnImp.tV5AMIJCneIkp2IAF2 $2a$10$P1zZnMm8/KYVseSkkfh0T.i2cVwydZ5L/5rZEALWCo3f9TmVLmM9q

加密 123456: $2a$10$wtJie2Wc93SqCCri5u/f4uZX7ATSSyMxlrCTEkPmNHLl9Oa0QdLim

  • MD5 加密后的值举例:

比如加密 admin, MD5两次结果都一样 21232f297a57a5a743894a0e4a801fc3 21232f297a57a5a743894a0e4a801fc3

加密 123456: e10adc3949ba59abbe56e057f20f883e

初始化项目

(1) 创建一个 pwd_demo 的目录。

$ mkdir pwd_demo

(2) 使用 go mod 命令来管理包,设置项目的包名为 pwd_demo:

$ mkdir pwd_demo
$ go mod init pwd_demo

该命令会创建一个 go.mod 的文件,用于记录引入的包版本,类似于 node 的 package.json 或 php 的 composer.json 文件。

(3) 创建一个 main.go 文件:

package main

import (
	"fmt"
)

func main() {

	fmt.Println("=> hi password!")

}

(4) 运行代码

$ go run main.go

启动正常。

编写 utils 包 在 go 语言中,一个包就是一个目录,即同一个目录下的同级的所有go文件应该属于一个包。

这里我们创建一个 utils 目录,并将包名命名为 utils (即和目录名相同,不相同也可以)。

(1) 创建一个 utils 目录, 并创建一个 pwd.go 文件:

$ mkdir utils
$ cd utils
$ touch pwd.go

文件 pwd.go 代码如下: // 密码加密: pwdHash 同PHP函数 password_hash() // 密码验证: pwdVerify 同PHP函数

package utils

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


func PasswordHash(pwd string) (string, error) {
	bytes, err := bcrypt.GenerateFrompwd([]byte(pwd), bcrypt.DefaultCost)
	if err != nil {
		return "", err
	}

	return string(bytes), err
}

password_verify()
func PasswordVerify(pwd, hash string) bool {
	err := bcrypt.CompareHashAndpwd([]byte(hash), []byte(pwd))

	return err == nil
}

执行测试用例:

$ go test -v utils/pwd_test.go utils/pwd.go

按照提示,安装 crypto/bcrypt 包:

$ go get golang.org/x/crypto/bcrypt

像 md5 加密方法,在Go自带的包里都有,即 “crypto/md5” 。 但是自带的包里没有 bcrypt 机密库,在其 golang.org/x/crypto 加密扩展包里有,所以需要手动下载。

## 语言自带的
import "crypto/md5"

## 扩展子模块里,需要自己下载
import "golang.org/x/crypto/bcrypt"

如果不能下载,请使用 goproxy.io :

# 配置 GOPROXY 环境变量
export GOPROXY=https://goproxy.io,direct