You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.9 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package utils
import (
"crypto"
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"golang.org/x/crypto/bcrypt"
"net/url"
"os"
)
func Md5(str string) string {
hash := md5.New()
hash.Write([]byte(str))
bytes := hash.Sum(nil)
md5Str := hex.EncodeToString(bytes)
return md5Str
}
func Sign(params url.Values, signKey string) string {
fmt.Println(params.Encode() + "&signkey=" + signKey)
return Md5(params.Encode() + "&signkey=" + signKey)
}
func PasswordHash(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
func PasswordVerify(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
func RSASign(data []byte, filename string) (string, error) {
// 1、选择hash算法对需要签名的数据进行hash运算
myHash := crypto.SHA1
hashInstance := myHash.New()
hashInstance.Write(data)
hashed := hashInstance.Sum(nil)
// 2、读取私钥文件解析出私钥对象
privateKey, err := ReadParsePrivateKey(filename)
fmt.Println("signErr1", err)
if err != nil {
return "", err
}
// 3、RSA数字签名参数是随机数、私钥对象、哈希类型、签名文件的哈希串生成bash64编码
bytes, err := rsa.SignPKCS1v15(rand.Reader, privateKey, myHash, hashed)
fmt.Println("signErr2", err)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(bytes), nil
}
func RSAVerify(data []byte, base64Sig, filename string) error {
// 1、对base64编码的签名内容进行解码返回签名字节
bytes, err := base64.StdEncoding.DecodeString(base64Sig)
if err != nil {
return err
}
// 2、选择hash算法对需要签名的数据进行hash运算
myHash := crypto.SHA1
hashInstance := myHash.New()
hashInstance.Write(data)
hashed := hashInstance.Sum(nil)
// 3、读取公钥文件解析出公钥对象
publicKey, err := ReadParsePublicKey(filename)
if err != nil {
return err
}
// 4、RSA验证数字签名参数是公钥对象、哈希类型、签名文件的哈希串、签名后的字节
return rsa.VerifyPKCS1v15(publicKey, myHash, hashed, bytes)
}
// ReadParsePublicKey 读取公钥文件,解析公钥对象
func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) {
// 1、读取公钥文件获取公钥字节
publicKeyBytes, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
// 2、解码公钥字节生成加密对象
block, _ := pem.Decode(publicKeyBytes)
if block == nil {
return nil, errors.New("公钥信息错误!")
}
// 3、解析DER编码的公钥生成公钥接口
publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
// 4、公钥接口转型成公钥对象
publicKey := publicKeyInterface.(*rsa.PublicKey)
return publicKey, nil
}
// ReadParsePrivateKey 读取私钥文件,解析出私钥对象
func ReadParsePrivateKey(filename string) (*rsa.PrivateKey, error) {
// 1、读取私钥文件获取私钥字节
privateKeyBytes, err := os.ReadFile(filename)
fmt.Println(string(privateKeyBytes))
if err != nil {
return nil, err
}
// 2、解码私钥字节生成加密对象
block, _ := pem.Decode(privateKeyBytes)
if block == nil {
return nil, errors.New("私钥信息错误!")
}
fmt.Println("blockType", block.Type)
// 3、解析DER编码的私钥生成私钥对象
if block.Type == "RSA PRIVATE KEY" {
return x509.ParsePKCS1PrivateKey(block.Bytes)
}
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
rsaKey, ok := privateKey.(*rsa.PrivateKey)
if ok {
return rsaKey, nil
} else {
return nil, errors.New("私钥错误")
}
}
func Sha1(data string) string {
h := sha1.New()
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}