编辑代码

package main
import "fmt"
import (
	"crypto"
    "crypto/md5"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
    "encoding/json"
    "reflect"
	"encoding/hex"
)
const (
	privateKey = `-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDY4HhGmw99mqAqkwjQdQg04M4Ny1RqilunCD3+DMT9eTqeLkzu68dc2AX8pFlwyL+BOE2knz8sWuY287zrk0+wC+kNmq/agDMSHW/HsQOEq5LQ00sca1cmcc3BMb82yAUMJDxxt2cnknWoXziGtEIu+AMU3X/aULoztd67sq5hPvElEzKc3O8uq6k3UoG5LXDIKcNnkK7z/aoS673ie9/zj9Rjl8QTXh77WuzOfLeKbcR9whcokqnyLfM9vnskXdwTZrZzrDTx0aZ4YNZgyvlcKRqQlty6oVE2JuW6Aq2F+odN8f4Gh49hWFX7q+WNQl+ycyLsGfiT+TceGIcTMq8ZAgMBAAECggEBAKFJ1skTmmKb8w+Wh9CXqMHCihtiIuaU/PJsw8XC82FanghzgI2S1ZIrqdAo3cdt1FYibEPIlq/C7kDh5ZcA2Buhz/FpH+0MuG55a98Duw0YmDgrW0nIXmjd69oIyB7ShEZyUG11qwaX+l58akprlmjd01TaIbJXpRK95+aJTPxN9sJTaAZ91bydswO4cvPJd0aC7LO1BsEvLYOP0uyEDrOMIDUKiSTGgzwGHkqbNsSaY0UaPu+HFfwLY/GfldhuCiqXChBGZf+4ER741EiUVl3qNWOY+6x0WQuPNdXvKSrVRAIRec8gcv3snxbfrJMAry+zT93pt3ih6x+gE+5J4p0CgYEA++F6PGQ8BykOwxwwJ1UQ2PhKa3pFy5LFUA8QPU7C+4OEDiG6gChl9KAD0hMHl99DJSaRo9rfsQIv+z0DzAmgNh/gY0unMcqqeXlKXMa0sIl06cQUhMNwCYY8+YLhB/VYcKsv34CTymC24uVRX/SqO2/mHZtEKgna+h1O3Yht6a8CgYEA3Gxx8HsVX5OC4Uw7WJaV8MCMyLhoKGQNMu11ie9mHhiZPDSv7idn9XuOma+S4zFS/lmSODmWWVnf5KhutxEukrqrwXeMzYuvVhjHIpkPPxbDJz7iiodfY4lGeBfSTWxg296SIiI/oAM7j+eucYSAk/0Jfvo8FLCMYkGHUhjZTbcCgYBmLdACk77uQK+mYtb9/bo56m92LkIGFWJJ2fKCjGL42R9HBFO+DaVemVMzc1jPOVjpxz2ptO6txe9lAhl6OiVuD3xdi6Elx8tkP9n0zP8b5ocxFcQlH4thsb0mkvtq2RKpkih3iJdrr9RBMznRrVUpi3lUZVo/m4PjluQZZnEALQKBgBvxU3Bc6hS3qnvNIijUziU7A53eYrXcGSA/ogreYl+mVqafNz5FmJQyGZ25+DD867x6tmKSSlEBZ7Sg9YgXkYPgTi20bhEQiCWt9nCYXqpsxEiRXD6bcqg3mstWmb5e4th8mqHhHZe3UTGo+SBC39ni1fVW247z4pgCHpl1tPZ5AoGBAI5q0wJhcuonoR3hChrltshRT41uM+U6MTxBpUOkicbg8WvIvyRrERppG7EqN+kEG4nYSxQzQhe7N5VaE7kanQE4cl59qkqPCptjoBcxiuIhLfrkbARCknzqFLUzqCyoi4kWxYWiLaCK5uO6VuQfY+siP45jNCHm+v4SbjjY/ecN
-----END PRIVATE KEY-----`
)

const (
	payerMaxPublicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApeo7M6vybSYxCN3eS4T4l9dtyVkfVtIbxeOljYL1lqaQr3vBbmS9sgsBM/Lt0mZZ4M2EF8Fq5KXlYwLTrWsXstjBzAcIBYThBK4DfnpEhBcXVCn7GRYZ2cQxLaSgJsbHYMVVX0X/5Tb4qZaGZuNiXsNi5D74nz0E/8EkUWesGWtw6tmtnJBzhGxylgX3Zm42GUhuNdWiC/nKthW0vw/S+pnOk1eZqzZrvKlnjpGdqPZTf0R0bEMJdKPAXufPZN1wsphWWw1jKmyWCgDKthljXcKzydu5yR7TrItGz2KlIJem/5P2+428F9Lt3S+cM6wNlHpF+6vyXbJCrVSJtbMSmwIDAQAB
-----END PUBLIC KEY-----`

)
// 解析私钥
// 解析私钥
func MD5(data []byte) string {
	has := md5.Sum(data)
	return fmt.Sprintf("%x", has)
}


func getParams(req interface{}) (map[string]string, error) {
	typeOf := reflect.TypeOf(req)
	if typeOf.Kind() != reflect.Ptr {
		return nil, errors.New("req must be a pointer")
	}

	val := reflect.ValueOf(req).Elem()
	typ := val.Type()
	if val.Kind() != reflect.Struct {
		return nil, errors.New("val must be a struct")
	}

	params := make(map[string]string)
	for i := 0; i < val.NumField(); i++ {
		if !val.Field(i).CanInterface() {
			continue
		}
		typFd := typ.Field(i)
		valFd := val.Field(i)

		ftyp := typFd.Type.Kind()
		//if ftyp == reflect.Struct ||
		//	ftyp == reflect.Interface {
		//	continue
		//}
		if ftyp == reflect.Ptr {
			if valFd.IsNil() {
				continue
			}
			valFd = valFd.Elem()
		}

		params[typFd.Tag.Get("json")] = func() string {
			if ftyp != reflect.String {
				return fmt.Sprintf("%v", valFd)
			}
			return valFd.String()
		}()
	}
	fmt.Println("getParams", params)
	return params, nil
}


func ParsePrivateKey(privateKey string) (*rsa.PrivateKey, error) {
	block, _ := pem.Decode([]byte(privateKey))
	if block == nil {
		return nil, errors.New("私钥信息错误!")
	}
	priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	rsaPrivateKey, ok := priKey.(*rsa.PrivateKey)
	if !ok {
		return nil, fmt.Errorf("parsed key is not an RSA private key")
	}

	return rsaPrivateKey, nil
}

func GenRSASign(params map[string]string) string {

    // params, err := getParams(req)
    // if err != nil {
	// 	fmt.Println("ParsePrivateKey err :", err)
	// 	return ""
	// }
	priKey, err := ParsePrivateKey(privateKey)
	if err != nil {
		fmt.Println("ParsePrivateKey err :", err)
		return ""
	}
	b, _ := json.Marshal(params)
    fmt.Println("=======00", string(b))

	hashed := sha256.Sum256(b)
	signature, err := rsa.SignPKCS1v15(rand.Reader, priKey, crypto.SHA256, hashed[:])
	if err != nil {
		fmt.Println("err Failed to sign the request body:", err)
		return ""
	}
    fmt.Println("=======", base64.StdEncoding.EncodeToString(signature))
	return base64.StdEncoding.EncodeToString(signature)
}


func RSAVerify(src []byte, sign []byte) (pass bool, err error) {
	//步骤1,加载RSA的公钥
	block, _ := pem.Decode([]byte(payerMaxPublicKey))
	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		fmt.Printf("Failed to parse RSA public key: %s\n", err)
		return
	}
	rsaPub, _ := pub.(*rsa.PublicKey)

	//步骤2,计算代签名字串的SHA1哈希
	hashed := sha256.Sum256(src)
	//步骤3,base64 decode,必须步骤,支付宝对返回的签名做过base64 encode必须要反过来decode才能通过验证
	data, _ := base64.StdEncoding.DecodeString(string(sign))

	hexSig := hex.EncodeToString(data)
	fmt.Printf("base decoder: %v, %v\n", string(sign), hexSig)

	//步骤4,调用rsa包的VerifyPKCS1v15验证签名有效性
	err = rsa.VerifyPKCS1v15(rsaPub, crypto.SHA256, hashed[:], data)
	if err != nil {
		fmt.Println("Verify sig error, reason: ", err)
		return false, err
	}
	return true, nil
}

func main () {
    //JSRUN引擎2.0,支持多达30种语言在线运行,全仿真在线交互输入输出。
    fmt.Println("Hello world!   -  go.jsrun.net ")

    tests := []map[string]string{
        {"merchantId":"SP19529488","bizType":"CUSTOMIZE","version":"2.3","orderId":"1781390517431621299578","userId":"1324411","subject":"Android 套餐一【勿上架】","countryCode":"ID","currency":"IDR","totalAmount":"9999","frontCallBackScheme":"ukiapp://ucoinhome/payermax","reference":"1324411","showResult":"1","receipt":"1","expireTime":"1800","appId":"64d7fd9ee67149edaf1dc04dc5f0c8c6"},
	}
    for _, tt := range tests {
		GenRSASign(tt)
	}
    resp := map[string]interface{}{
        "data": map[string]interface{}{
        "tradeNo": "T2023082406066925034261",
        "orderId": "1780520453336721299574",
        "status": 2,
    },
    "bizCode": "0000",
    }
    b, _ := json.Marshal(resp)
    sign := "1oboiExExZpSYyKOv+TbEmgLOqqYsqMEwGQydkPgfEfFPK4VTV/6vURUqfPm/SnJ8tBy5rkxZ8R1+/ZrW5T7CVmOiKhIBw/4LPv5Xj08MmL5qPPrdg+UbnF+G7b2FEyAfFblF+CdXnn89k7r0Ma/6JEr0bIpJ4BmOmuzMEtDdhCQZ43kXD40P5Cf1MkvrSO4Au+hJtRBVRVtCCGJt1bTRA1G7BvXj7DKUaF6w3yikf7D1DYfD6vDO95Tdzy+Ge1fl/oZK48JQNii0Xouekd76UARm54q9iynSy8a4Hj1dHzyTGa7q6uooALD57ryQRA/5Dt1Rzej/tTcQyVIl0Nbiw=="
	ok, _ := RSAVerify(b, []byte(sign))
    fmt.Println("Verify======: ", resp, ok)

}