73 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package crypto
 | |
| 
 | |
| import (
 | |
| 	"crypto/rand"
 | |
| 	"encoding/hex"
 | |
| 	"fmt"
 | |
| 	"strings"
 | |
| 
 | |
| 	"golang.org/x/crypto/bcrypt"
 | |
| 	"golang.org/x/crypto/scrypt"
 | |
| )
 | |
| 
 | |
| // ******************** scrypt ********************
 | |
| 
 | |
| // ScryptHashPassword scrypt 加密
 | |
| // password 原始密码
 | |
| func ScryptHashPassword(password string) (string, error) {
 | |
| 	// example for making salt - https://play.golang.org/p/_Aw6WeWC42I
 | |
| 	salt := make([]byte, 32)
 | |
| 	_, err := rand.Read(salt)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	// using recommended cost parameters from - https://godoc.org/golang.org/x/crypto/scrypt
 | |
| 	hash, err := scrypt.Key([]byte(password), salt, 32768, 8, 1, 32)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	// return hex-encoded string with salt appended to password
 | |
| 	hashedPW := fmt.Sprintf("%s.%s", hex.EncodeToString(hash), hex.EncodeToString(salt))
 | |
| 	return hashedPW, nil
 | |
| }
 | |
| 
 | |
| // ScryptComparePassword 判断密码是否正确
 | |
| // storedPassword 加密密码
 | |
| // suppliedPassword 原始密码
 | |
| func ScryptComparePassword(storedPassword string, suppliedPassword string) (bool, error) {
 | |
| 	pwdSalt := strings.Split(storedPassword, ".")
 | |
| 
 | |
| 	// check supplied password salted with hash
 | |
| 	salt, err := hex.DecodeString(pwdSalt[1])
 | |
| 	if err != nil {
 | |
| 		return false, fmt.Errorf("unable to verify user password")
 | |
| 	}
 | |
| 
 | |
| 	hash, err := scrypt.Key([]byte(suppliedPassword), salt, 32768, 8, 1, 32)
 | |
| 	if err != nil {
 | |
| 		return false, err
 | |
| 	}
 | |
| 	return hex.EncodeToString(hash) == pwdSalt[0], nil
 | |
| }
 | |
| 
 | |
| // ******************** bcrypt ********************
 | |
| 
 | |
| // BcryptHashPassword bcrypt 加密
 | |
| // password 原始密码
 | |
| func BcryptHashPassword(password string) ([]byte, error) {
 | |
| 	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("failed to hash password: %w", err)
 | |
| 	}
 | |
| 	return hashedPassword, nil
 | |
| }
 | |
| 
 | |
| // BcryptComparePassword 判断密码是否正确
 | |
| // hashedPassword 加密密码
 | |
| // password 原始密码
 | |
| func BcryptComparePassword(hashedPassword []byte, password string) error {
 | |
| 	return bcrypt.CompareHashAndPassword(hashedPassword, []byte(password))
 | |
| }
 |