2024-07-08 18:01:02 +08:00
|
|
|
|
package util
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"crypto"
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"crypto/rsa"
|
|
|
|
|
"crypto/sha256"
|
|
|
|
|
"encoding/asn1"
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"encoding/hex"
|
2024-07-10 10:44:07 +08:00
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
2024-07-08 18:01:02 +08:00
|
|
|
|
"github.com/tjfoc/gmsm/sm2"
|
|
|
|
|
"github.com/tjfoc/gmsm/x509"
|
|
|
|
|
"math/big"
|
2024-07-10 10:44:07 +08:00
|
|
|
|
"net/url"
|
2024-07-08 18:01:02 +08:00
|
|
|
|
"qteam/app/third/dfpOpenSdk/config"
|
2024-07-10 10:44:07 +08:00
|
|
|
|
"strings"
|
2024-07-08 18:01:02 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 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) {
|
2024-07-10 10:44:07 +08:00
|
|
|
|
decodeString, err := base64.StdEncoding.DecodeString(encodedPrivateKey)
|
2024-07-08 18:01:02 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2024-07-10 10:44:07 +08:00
|
|
|
|
privateKey, err := x509.ReadPrivateKeyFromHex(hex.EncodeToString(decodeString))
|
2024-07-08 18:01:02 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-10 10:44:07 +08:00
|
|
|
|
// 解析密文
|
|
|
|
|
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)
|
2024-07-08 18:01:02 +08:00
|
|
|
|
|
|
|
|
|
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)
|
2024-07-10 10:44:07 +08:00
|
|
|
|
|
|
|
|
|
pr, _ := hex.DecodeString(privateKey)
|
|
|
|
|
pb, _ := hex.DecodeString(publicKey)
|
|
|
|
|
|
|
|
|
|
privateKey = base64.StdEncoding.EncodeToString(pr)
|
|
|
|
|
publicKey = base64.StdEncoding.EncodeToString(pb)
|
2024-07-08 18:01:02 +08:00
|
|
|
|
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()]
|
|
|
|
|
}
|
2024-07-10 10:44:07 +08:00
|
|
|
|
return base64.StdEncoding.EncodeToString(buffer)
|
|
|
|
|
//return string(buffer)
|
2024-07-08 18:01:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
2024-07-10 10:44:07 +08:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|