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

386 lines
11 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
}
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()
pwd = "9A9A4QyNz/pc8kZZXzhXOQ=="
// 使用SM4算法加密请求报文内容
encData, err = SM4Encrypt(bodyParamString, pwd)
if err != nil {
return "", err
}
// 使用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 "", err
}
}
encryptBodyParamMap["encData"] = encData
encryptBodyParamMap["encPassword"] = encPassword
// 根据flag的值决定返回JSON字符串还是拼接的字符串
if flag {
return JSONMarshal(encryptBodyParamMap)
} else {
return MapToString(encryptBodyParamMap), nil
}
}
// form 形式
func EncryptBody2(bodyParamString string, keyConfigure config.KeyConfigure, flag bool) (formData url.Values, err error) {
//encryptBodyParamMap := make(map[string]string, 10)
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)
}
//encryptBodyParamMap["encData"] = encData
//encryptBodyParamMap["encPassword"] = encPassword
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, "&")
}
// EncryptBySM2PublicKey2 sm2公钥加密, 结果为base64格式
func EncryptBySM2PublicKey2(encodedPublicKey string, contentBytes []byte) (string, error) {
decodeKey, err := base64.StdEncoding.DecodeString(encodedPublicKey)
if err != nil {
return "", err
}
hexPublic := hex.EncodeToString(decodeKey)
pubKey, err := x509.ReadPublicKeyFromHex(hexPublic)
if err != nil {
return "", err
}
//
cipherText, err := sm2.Encrypt(pubKey, contentBytes, rand.Reader, sm2.C1C3C2)
return base64.StdEncoding.EncodeToString(cipherText), nil
}
//// Sm2DecryptLoc sm2私钥解密, 结果为base64格式
//func Sm2DecryptLoc(publicKeyStr, privateKeyStr, cipherText string) (string, error) {
// publicKeyObj, err := StringToPublicKey(publicKeyStr)
// if err != nil {
// fmt.Println(err)
// }
// privateKeyObj, err := StringToPrivateKey(privateKeyStr, publicKeyObj)
// if err != nil {
// fmt.Println(err)
// }
// decodeString, err := hex.DecodeString(cipherText)
// decrypt, err := sm2.Decrypt(privateKeyObj, decodeString, sm2.C1C2C3)
// if err != nil {
// fmt.Println(err)
// }
// resultStr := string(decrypt)
// fmt.Println("解密后的字符串:", resultStr)
// return resultStr, nil
//}
// StringToPrivateKey 私钥还原为 sm2.PrivateKey对象(与java中org.bouncycastle.crypto生成的公私钥完全互通使用)
func StringToPrivateKey(privateKeyStr string, publicKey *sm2.PublicKey) (*sm2.PrivateKey, error) {
privateKeyBytes, err := hex.DecodeString(privateKeyStr)
if err != nil {
return nil, err
}
priHex := hex.EncodeToString(privateKeyBytes)
// 将字节切片转换为大整数
d := new(big.Int).SetBytes([]byte(priHex))
// 创建 sm2.PrivateKey 对象
privateKey := &sm2.PrivateKey{
PublicKey: *publicKey,
D: d,
}
return privateKey, nil
}
// StringToPublicKey 公钥字符串还原为 sm2.PublicKey 对象(与java中org.bouncycastle.crypto生成的公私钥完全互通使用)
func StringToPublicKey(publicKeyStr string) (*sm2.PublicKey, error) {
decodeString, err := base64.StdEncoding.DecodeString(publicKeyStr)
if err != nil {
return nil, err
}
public, err := x509.ReadPublicKeyFromHex(hex.EncodeToString(decodeString))
if err != nil {
return public, err
}
return public, nil
}