XinYeYouKu/app/third/dfpOpenSdk/util/signature.go

292 lines
7.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package util
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/tjfoc/gmsm/sm2"
"github.com/tjfoc/gmsm/x509"
"math/big"
"net/url"
"qteam/app/third/dfpOpenSdk/config"
"strings"
)
// SignatureByRSA RSA签名
func SignatureByRSA(content string, privateKey string) string {
decodeString, err := base64.StdEncoding.DecodeString(privateKey)
if err != nil {
return ""
}
hash := sha256.New()
hash.Write([]byte(content))
//Step3获得明文的散列值
hashText := hash.Sum(nil)
private, err := x509.ParsePKCS1PrivateKey(decodeString)
sign, err := rsa.SignPKCS1v15(
rand.Reader,
private,
crypto.SHA256,
hashText,
)
return base64.StdEncoding.EncodeToString(sign)
}
type sm2Signature struct {
R, S *big.Int
}
// SignatureBySM2 SM2签名
func SignatureBySM2(content string, privateKey string) (string, error) {
decodeString, _ := base64.StdEncoding.DecodeString(privateKey)
pri, err := FormatPri(decodeString)
if err != nil {
return "", err
}
sign, _ := pri.Sign(rand.Reader, []byte(content), nil)
signature := sm2Signature{}
_, err = asn1.Unmarshal(sign, &signature)
if err != nil {
return "", err
}
rbytes := signature.R.Bytes()
sbytes := signature.S.Bytes()
resultbytes := append(rbytes, sbytes...)
return base64.StdEncoding.EncodeToString(resultbytes), nil
}
func VerifyBySM2(contentBytes []byte, sign string, publicKey string) (bool, error) {
pubKey := FromPublicKey(publicKey)
//pri, err := FormatPri(decodeString)
//if err != nil {
// log.Fatal(err)
// return false, err
//}
bytes, _ := base64.StdEncoding.DecodeString(sign)
verify := pubKey.Verify(contentBytes, bytes)
//verify := pri.Verify(contentBytes, bytes)
return verify, nil
}
// EncryptBySM2PublicKey sm2公钥加密, 结果为base64格式
func EncryptBySM2PublicKey(encodedPublicKey string, contentBytes []byte) (string, error) {
decodeString, err2 := base64.StdEncoding.DecodeString(encodedPublicKey)
if err2 != nil {
return "", nil
}
public, err := x509.ReadPublicKeyFromHex(hex.EncodeToString(decodeString))
if err != nil {
return "", err
}
//
asn1Encrypt, err := public.EncryptAsn1(contentBytes, rand.Reader)
if err != nil {
return "", err
}
unmarshal, err := sm2.CipherUnmarshal(asn1Encrypt)
return base64.StdEncoding.EncodeToString(unmarshal), nil
}
// DecryptBySM2PrivateKey sm2私钥解密
func DecryptBySM2PrivateKey(encodedPrivateKey string, contentBytes []byte) ([]byte, error) {
decodeString, err := base64.StdEncoding.DecodeString(encodedPrivateKey)
if err != nil {
return nil, err
}
privateKey, err := x509.ReadPrivateKeyFromHex(hex.EncodeToString(decodeString))
if err != nil {
return nil, err
}
// 解析密文
base64Content, err := base64.StdEncoding.DecodeString(string(contentBytes))
if err != nil {
return nil, err
}
asn1Encrypt, err := sm2.CipherMarshal(base64Content)
if err != nil {
return nil, err
}
plaintext, err := privateKey.DecryptAsn1(asn1Encrypt)
if err != nil {
return nil, err
}
return plaintext, nil
}
// FormatPri 从私钥base64格式生成对应私钥格式
func FormatPri(priByte []byte) (*sm2.PrivateKey, error) {
// 椭圆曲线
c := sm2.P256Sm2()
// k倍点
k := new(big.Int).SetBytes(priByte)
priv := new(sm2.PrivateKey)
priv.PublicKey.Curve = c
priv.D = k
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
return priv, nil
}
func FromPublicKey(publicKey string) *sm2.PublicKey {
decodeKey, _ := base64.StdEncoding.DecodeString(publicKey)
hexPublic := hex.EncodeToString(decodeKey)
pubKey, _ := x509.ReadPublicKeyFromHex(hexPublic)
return pubKey
}
func SM2_GenerateKeyPair() (publicKey string, privateKey string, err error) {
privKey, err := sm2.GenerateKey(nil) // 生成密钥对
if err != nil {
return
}
privateKey = x509.WritePrivateKeyToHex(privKey)
publicKey = x509.WritePublicKeyToHex(&privKey.PublicKey)
pr, _ := hex.DecodeString(privateKey)
pb, _ := hex.DecodeString(publicKey)
privateKey = base64.StdEncoding.EncodeToString(pr)
publicKey = base64.StdEncoding.EncodeToString(pb)
return
}
func SM4_GenerateKeyPair() string {
str := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
buffer := make([]byte, 16)
for i := 0; i < 16; i++ {
nextInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(str))))
buffer[i] = str[nextInt.Int64()]
}
return base64.StdEncoding.EncodeToString(buffer)
//return string(buffer)
}
func encryptBody(bodyParamString string, keyConfigure config.KeyConfigure, flag bool) {
encryptBodyParamMap := make(map[string]string, 10)
var encData string
var encPassword string
if keyConfigure.RespSignAlgorithm == "sm4" {
pwd := SM4_GenerateKeyPair()
encData, _ = Sm4Encrypt(bodyParamString, pwd)
encPassword, _ = SignatureBySM2(bodyParamString, keyConfigure.PriKey)
}
encryptBodyParamMap["encData"] = encData
encryptBodyParamMap["encPassword"] = encPassword
}
// EncryptBody 加密请求报文内容 json 形式
func EncryptBody(bodyParamString string, keyConfigure config.KeyConfigure, flag bool) (string, error) {
encryptBodyParamMap := make(map[string]string, 10)
var encData string
var encPassword string
var err error
if keyConfigure.RespSignAlgorithm == "sm4" {
// 生成SM4密钥
pwd := SM4_GenerateKeyPair()
// 使用SM4算法加密请求报文内容
encData, err = Sm4Encrypt(bodyParamString, pwd)
if err != nil {
return "", err
}
// sm2加密SM4密钥
encPassword, err = EncryptBySM2PublicKey(keyConfigure.RespPubKey, []byte(pwd))
if err != nil {
return "", err
}
}
encryptBodyParamMap["encData"] = encData
encryptBodyParamMap["encPassword"] = encPassword
// 根据flag的值决定返回JSON字符串还是拼接的字符串
if flag {
return JSONMarshal(encryptBodyParamMap)
} else {
return MapToString(encryptBodyParamMap), nil
}
}
// EncryptFormBody 加密请求报文内容 form 形式
func EncryptFormBody(bodyParamString string, keyConfigure config.KeyConfigure) (formData url.Values, err error) {
var encData string
var encPassword string
formData = url.Values{}
if keyConfigure.RespSignAlgorithm == "sm4" {
// 生成SM4密钥
pwd := SM4_GenerateKeyPair()
//pwd = "a0l5MEZwMFpVQ08zaUszWg=="
// 使用SM4算法加密请求报文内容
encData, err = Sm4Encrypt(bodyParamString, pwd)
if err != nil {
return
}
fmt.Println("bodyParamString=", bodyParamString)
fmt.Println("pwd=", pwd)
// 使用SM2公钥对SM4密钥进行加密
//// 使用自己的密钥加解密
//{
// pub, pri, _ := SM2_GenerateKeyPair()
// fmt.Println("pub=", pub)
// fmt.Println("pri=", pri)
// encPassword, err = EncryptBySM2PublicKey(pub, []byte(pwd))
// if err != nil {
// return "", err
// }
// //fmt.Println("pub=", keyConfigure.RespPubKey)
// //fmt.Println("encPassword=", encPassword)
// content, err := DecryptBySM2PrivateKey(pri, []byte(encPassword))
// if err != nil {
// return "", err
// }
// fmt.Println("加密内容content=", pwd)
// fmt.Println("解密内容content=", string(content))
//}
encPassword, err = EncryptBySM2PublicKey(keyConfigure.RespPubKey, []byte(pwd))
if err != nil {
return
}
fmt.Println("RespPubKey = ", keyConfigure.RespPubKey)
}
formData.Set("encData", encData)
formData.Set("encPassword", encPassword)
fmt.Println("encData=", encData)
fmt.Println("encPassword=", encPassword)
return
}
// JSONMarshal 将map转换为JSON字符串
func JSONMarshal(m map[string]string) (string, error) {
b, err := json.Marshal(m)
if err != nil {
return "", err
}
return string(b), nil
}
// MapToString 将map拼接成字符串简单实现不考虑编码问题
func MapToString(m map[string]string) string {
var parts []string
for k, v := range m {
parts = append(parts, fmt.Sprintf("%s=%s", k, v))
}
return strings.Join(parts, "&")
}