Go實現隨機加鹽密碼認證

爲什麼要加密

人們往往有使用同一密碼的習慣, 爲了防止數據庫意外泄露/破壞和出於保護用戶隱私的目的, 不應在數據庫裏存入用戶密碼明文

實現

代碼

package main

import (
	"fmt"
	"golang.org/x/crypto/bcrypt"
	"time"
)

func main() {
	password := []byte("thisIsPassWord")
	nowG := time.Now()
	hashedPassword, _ := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)
	fmt.Println("加密後", string(hashedPassword), "耗時", time.Now().Sub(nowG))
	nowC := time.Now()
	err := bcrypt.CompareHashAndPassword(hashedPassword, password)
	fmt.Println("驗證耗費時間", time.Now().Sub(nowC))
	fmt.Println(err)
}

// 結果
// 加密後 $2a$10$ESkb/bwSyISLgq1bOH0C2utXdb.hcH9oBQD1hUnfDOzm4bMKK6EX2 耗時 67.9985ms
// 驗證耗費時間 66.0008ms
// <nil>  

將加密後的密碼串存入數據表, 然後用戶登錄傳遞明文密碼(也可以前段加密後端再解密成明文)進行驗證

密碼串解析

$2a$10$ESkb/bwSyISLgq1bOH0C2utXdb.hcH9oBQD1hUnfDOzm4bMKK6EX2
$ 爲分隔符
2a bcrypt加密版本號
10 Cost值
ESkb/bwSyISLgq1bOH0C2utXdb 鹽
hcH9oBQD1hUnfDOzm4bMKK6EX2 密碼密文

優缺點

優點:
    單向HASH,不可解密
    鹽值隨機(有效防止彩虹表碰撞)
    破解時間成本極高
缺點:
    效率較慢(相較於mad5/sha算法)

源碼分析

// GenerateFromPassword returns the bcrypt hash of the password at the given
// cost. If the cost given is less than MinCost, the cost will be set to
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
// to compare the returned hashed password with its cleartext version.
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
	p, err := newFromPassword(password, cost)
	if err != nil {
		return nil, err
	}
	return p.Hash(), nil
}

// CompareHashAndPassword compares a bcrypt hashed password with its possible
// plaintext equivalent. Returns nil on success, or an error on failure.
func CompareHashAndPassword(hashedPassword, password []byte) error {
	p, err := newFromHash(hashedPassword)
	if err != nil {
		return err
	}

	otherHash, err := bcrypt(password, p.cost, p.salt)
	if err != nil {
		return err
	}

	otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
	if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
		return nil
	}

	return ErrMismatchedHashAndPassword
}

就是用已有的加密哈希的salt和cost對現有密碼進行加密來確認密碼密文是否一致

補充

1 最主要還是得用戶的密碼設置複雜一些(可以考慮強制), 最好是大小寫加特殊字符, 還有就是提醒用戶儘量不同網站用不同的密碼
2 可以在密碼裏面加一些固有字段, 也能提升安全等級, 比如在前後或者在中間加參數再進行加密解密(用戶不改我們幫他改)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章