不少系統都是將密碼進行一次 MD5 或 SHA1 Hash後存入數據庫中。這樣的密碼抵擋不住字典攻擊。所謂字典攻擊,就是將經常使用密碼進行Hash後作成一個字典,破解的時候,只須要查字典就能知道對應的明文密碼。golang

爲了抵禦字典攻擊,推薦的作法是使用 密碼 + 鹽(一串隨機數) 再Hash的方式。每一個密碼對應一個不一樣的隨機數。這個方法,其實是將密碼人爲地拓展了N位,致使密碼長度大增,使得攻擊者沒法構造這麼大的一個字典。正則表達式

Go語言提供了一種較爲安全的加密方式,使用GoLang golang.org/x/crypto/bcrypt 模塊,經過該模塊能夠快速實現密碼的存儲處理。數據庫

package main

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

type User struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}

func main() {
	fmt.Println("====模擬註冊====")
	u0 := User{}
	u0.Password = "pwd" //模擬註冊是傳遞的密碼
	hash, err := bcrypt.GenerateFromPassword([]byte(u0.Password), bcrypt.DefaultCost) //加密處理
	if err != nil {
		fmt.Println(err)
	}
	encodePWD := string(hash) // 保存在數據庫的密碼,雖然每次生成都不一樣,只需保存一份便可
	fmt.Println(encodePWD)

	fmt.Println("====模擬登陸====")
	u1:=User{}
	u1.Password=encodePWD //模擬從數據庫中讀取到的 通過bcrypt.GenerateFromPassword處理的密碼值
	loginPwd:="pwd" //用戶登陸時輸入的密碼
	// 密碼驗證
	err = bcrypt.CompareHashAndPassword([]byte(u1.Password), []byte(loginPwd)) //驗證(對比)
	if err != nil {
		fmt.Println("pwd wrong")
	} else {
		fmt.Println("pwd ok")
	}

}

運行效果:json

第一次運行:安全

第二次運行:加密

說明:每次運行,計算的密碼值都不一樣。所以使用GoLang golang.org/x/crypto/bcrypt 模塊對密碼進行處理,能夠避免字典攻擊。spa

附:密碼強弱的判斷

方法1:正則表達式判斷(長度、大小寫、特殊字符)code

方法2:創建一個若密碼錶,依據表中的密碼判斷是否爲若密碼blog

注:以上2種方法能夠結合使用string