123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- package utils
- import (
- "crypto/md5"
- "crypto/rand"
- "crypto/sha256"
- "crypto/sha512"
- "encoding/base64"
- "encoding/hex"
- "io"
- mt "math/rand"
- "strconv"
- "strings"
- )
- const (
- saltSize = 16
- delmiter = "$"
- stretching_password = 500
- salt_local_secret = "ahfw*&TGdsfnbi*^Wt"
- )
- //加密密码
- func PasswordHash(pass string) (string, error) {
- saltSecret, err := salt_secret()
- if err != nil {
- return "", err
- }
- salt, err := salt(salt_local_secret + saltSecret)
- if err != nil {
- return "", err
- }
- interation := randInt(1, 20)
- hash, err := hash(pass, saltSecret, salt, int64(interation))
- if err != nil {
- return "", err
- }
- interationString := strconv.Itoa(interation)
- password := saltSecret + delmiter + interationString + delmiter + hash + delmiter + salt
- return password, nil
- }
- //校验密码是否有效
- func PasswordVerify(hashing string, pass string) (bool, error) {
- data := trimSaltHash(hashing)
- interation, _ := strconv.ParseInt(data["interation_string"], 10, 64)
- has, err := hash(pass, data["salt_secret"], data["salt"], int64(interation))
- if err != nil {
- return false, err
- }
- if (data["salt_secret"] + delmiter + data["interation_string"] + delmiter + has + delmiter + data["salt"]) == hashing {
- return true, nil
- } else {
- return false, nil
- }
- }
- func hash(pass string, salt_secret string, salt string, interation int64) (string, error) {
- var passSalt = salt_secret + pass + salt + salt_secret + pass + salt + pass + pass + salt
- var i int
- hashPass := salt_local_secret
- hashStart := sha512.New()
- hashCenter := sha256.New()
- hashOutput := sha256.New224()
- i = 0
- for i <= stretching_password {
- i = i + 1
- _, err := hashStart.Write([]byte(passSalt + hashPass))
- if err != nil {
- return "", err
- }
- hashPass = hex.EncodeToString(hashStart.Sum(nil))
- }
- i = 0
- for int64(i) <= interation {
- i = i + 1
- hashPass = hashPass + hashPass
- }
- i = 0
- for i <= stretching_password {
- i = i + 1
- _, err := hashCenter.Write([]byte(hashPass + salt_secret))
- if err != nil {
- return "", err
- }
- hashPass = hex.EncodeToString(hashCenter.Sum(nil))
- }
- if _,err := hashOutput.Write([]byte(hashPass + salt_local_secret)); err != nil {
- return "", err
- }
- hashPass = hex.EncodeToString(hashOutput.Sum(nil))
- return hashPass, nil
- }
- func trimSaltHash(hash string) map[string]string {
- str := strings.Split(hash, delmiter)
- return map[string]string{
- "salt_secret": str[0],
- "interation_string": str[1],
- "hash": str[2],
- "salt": str[3],
- }
- }
- func salt(secret string) (string, error) {
- buf := make([]byte, saltSize, saltSize+md5.Size)
- _, err := io.ReadFull(rand.Reader, buf)
- if err != nil {
- return "", err
- }
- hash := md5.New()
- hash.Write(buf)
- hash.Write([]byte(secret))
- return hex.EncodeToString(hash.Sum(buf)), nil
- }
- func salt_secret() (string, error) {
- rb := make([]byte, randInt(10, 100))
- _, err := rand.Read(rb)
- if err != nil {
- return "", err
- }
- return base64.URLEncoding.EncodeToString(rb), nil
- }
- func randInt(min int, max int) int {
- return min + mt.Intn(max-min)
- }
|