Jerry 6 years ago
parent
commit
c7cd780419
2 changed files with 121 additions and 82 deletions
  1. 113 74
      alipay_service_api.go
  2. 8 8
      wechat_service_api.go

+ 113 - 74
alipay_service_api.go

@@ -79,50 +79,6 @@ func ParseAliPayNotifyResult(req *http.Request) (notifyReq *AliPayNotifyRequest,
 	return notifyReq, err
 }
 
-//解密支付宝开放数据
-//    encryptedData:包括敏感数据在内的完整用户信息的加密数据
-//    sessionKey:会话密钥
-//    beanPtr:需要解析到的结构体指针
-//    文档:https://docs.alipay.com/mini/introduce/aes
-//    文档:https://docs.open.alipay.com/common/104567
-func DecryptAliPayOpenDataToStruct(encryptedData, secretKey string, beanPtr interface{}) (err error) {
-	//验证参数类型
-	beanValue := reflect.ValueOf(beanPtr)
-	if beanValue.Kind() != reflect.Ptr {
-		return errors.New("传入参数类型必须是以指针形式")
-	}
-	//验证interface{}类型
-	if beanValue.Elem().Kind() != reflect.Struct {
-		return errors.New("传入interface{}必须是结构体")
-	}
-	aesKey, _ := base64.StdEncoding.DecodeString(secretKey)
-	ivKey := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-	secretData, _ := base64.StdEncoding.DecodeString(encryptedData)
-
-	block, err := aes.NewCipher(aesKey)
-	if err != nil {
-		return err
-	}
-	if len(secretData)%len(aesKey) != 0 {
-		return errors.New("encryptedData is error")
-	}
-
-	blockMode := cipher.NewCBCDecrypter(block, ivKey)
-	originData := make([]byte, len(secretData))
-	blockMode.CryptBlocks(originData, secretData)
-
-	if len(originData) > 0 {
-		originData = PKCS5UnPadding(originData)
-	}
-	//fmt.Println("originDataStr:", string(originData))
-	//解析
-	err = json.Unmarshal(originData, beanPtr)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
 //支付通知的签名验证和参数签名后的Sign
 //    aliPayPublicKey:支付宝公钥
 //    notifyReq:利用 gopay.ParseAliPayNotifyResult() 得到的结构体
@@ -171,7 +127,6 @@ func VerifyAliPayResultSign(aliPayPublicKey string, notifyReq *AliPayNotifyReque
 	}
 
 	pKey := FormatAliPayPublicKey(aliPayPublicKey)
-	//signData := sortAliPaySignParams(newBody)
 	signData := newBody.EncodeAliPaySignParams()
 
 	//log.Println("签名字符串:", signData)
@@ -182,6 +137,85 @@ func VerifyAliPayResultSign(aliPayPublicKey string, notifyReq *AliPayNotifyReque
 	return true, nil
 }
 
+//验证支付宝API返回结果或异步通知结果的Sign值
+//    aliPayPublicKey:支付宝公钥
+//    bean:支付宝API返回的结构体 aliRsp 或 异步通知解析的结构体 notifyReq
+//    返回参数ok:是否验签通过
+//    返回参数err:错误信息
+func VerifyAliPaySign(aliPayPublicKey string, bean interface{}) (ok bool, err error) {
+	if bean == nil {
+		return false, errors.New("bean is nil")
+	}
+	var (
+		bm BodyMap
+		bs []byte
+	)
+
+	bs, err = json.Marshal(bean)
+	if err != nil {
+		return false, err
+	}
+
+	bm = make(BodyMap)
+	err = json.Unmarshal(bs, &bm)
+	if err != nil {
+		return false, err
+	}
+
+	pKey := FormatAliPayPublicKey(aliPayPublicKey)
+	bodySign := bm.Get("sign")
+	bodySignType := bm.Get("sign_type")
+	bm.Remove("sign")
+	bm.Remove("sign_type")
+
+	signData := bm.EncodeAliPaySignParams()
+
+	err = verifyAliPaySign(signData, bodySign, bodySignType, pKey)
+	if err != nil {
+		return false, err
+	}
+	return true, nil
+}
+
+func verifyAliPaySign(signData, sign, signType, aliPayPublicKey string) (err error) {
+	var (
+		h     hash.Hash
+		hashs crypto.Hash
+	)
+	signBytes, err := base64.StdEncoding.DecodeString(sign)
+	if err != nil {
+		return err
+	}
+	//解析秘钥
+	block, _ := pem.Decode([]byte(aliPayPublicKey))
+	if block == nil {
+		return errors.New("支付宝公钥Decode错误")
+	}
+	key, err := x509.ParsePKIXPublicKey(block.Bytes)
+	if err != nil {
+		log.Println("x509.ParsePKIXPublicKey:", err)
+		return err
+	}
+	publicKey, ok := key.(*rsa.PublicKey)
+	if !ok {
+		return errors.New("支付宝公钥转换错误")
+	}
+	//判断签名方式
+	switch signType {
+	case "RSA":
+		hashs = crypto.SHA1
+	case "RSA2":
+		hashs = crypto.SHA256
+	default:
+		hashs = crypto.SHA256
+	}
+
+	h = hashs.New()
+	h.Write([]byte(signData))
+
+	return rsa.VerifyPKCS1v15(publicKey, hashs, h.Sum(nil), signBytes)
+}
+
 func jsonToString(v interface{}) (str string) {
 	if v == nil {
 		return ""
@@ -258,43 +292,48 @@ func FormatAliPayPublicKey(publicKey string) (pKey string) {
 	return
 }
 
-func verifyAliPaySign(signData, sign, signType, aliPayPublicKey string) (err error) {
-	var (
-		h     hash.Hash
-		hashs crypto.Hash
-	)
-	signBytes, err := base64.StdEncoding.DecodeString(sign)
-	if err != nil {
-		return err
+//解密支付宝开放数据
+//    encryptedData:包括敏感数据在内的完整用户信息的加密数据
+//    sessionKey:会话密钥
+//    beanPtr:需要解析到的结构体指针
+//    文档:https://docs.alipay.com/mini/introduce/aes
+//    文档:https://docs.open.alipay.com/common/104567
+func DecryptAliPayOpenDataToStruct(encryptedData, secretKey string, beanPtr interface{}) (err error) {
+	//验证参数类型
+	beanValue := reflect.ValueOf(beanPtr)
+	if beanValue.Kind() != reflect.Ptr {
+		return errors.New("传入参数类型必须是以指针形式")
 	}
-	//解析秘钥
-	block, _ := pem.Decode([]byte(aliPayPublicKey))
-	if block == nil {
-		return errors.New("支付宝公钥Decode错误")
+	//验证interface{}类型
+	if beanValue.Elem().Kind() != reflect.Struct {
+		return errors.New("传入interface{}必须是结构体")
 	}
-	key, err := x509.ParsePKIXPublicKey(block.Bytes)
+	aesKey, _ := base64.StdEncoding.DecodeString(secretKey)
+	ivKey := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+	secretData, _ := base64.StdEncoding.DecodeString(encryptedData)
+
+	block, err := aes.NewCipher(aesKey)
 	if err != nil {
-		log.Println("x509.ParsePKIXPublicKey:", err)
 		return err
 	}
-	publicKey, ok := key.(*rsa.PublicKey)
-	if !ok {
-		return errors.New("支付宝公钥转换错误")
-	}
-	//判断签名方式
-	switch signType {
-	case "RSA":
-		hashs = crypto.SHA1
-	case "RSA2":
-		hashs = crypto.SHA256
-	default:
-		hashs = crypto.SHA256
+	if len(secretData)%len(aesKey) != 0 {
+		return errors.New("encryptedData is error")
 	}
 
-	h = hashs.New()
-	h.Write([]byte(signData))
+	blockMode := cipher.NewCBCDecrypter(block, ivKey)
+	originData := make([]byte, len(secretData))
+	blockMode.CryptBlocks(originData, secretData)
 
-	return rsa.VerifyPKCS1v15(publicKey, hashs, h.Sum(nil), signBytes)
+	if len(originData) > 0 {
+		originData = PKCS5UnPadding(originData)
+	}
+	//fmt.Println("originDataStr:", string(originData))
+	//解析
+	err = json.Unmarshal(originData, beanPtr)
+	if err != nil {
+		return err
+	}
+	return nil
 }
 
 //换取授权访问令牌(默认使用utf-8,RSA2)

+ 8 - 8
wechat_service_api.go

@@ -117,12 +117,12 @@ func VerifyWeChatSign(apiKey, signType string, bean interface{}) (ok bool, err e
 		return false, errors.New("bean is nil")
 	}
 	var (
-		bodyMaps BodyMap
-		bs       []byte
+		bm BodyMap
+		bs []byte
 	)
 	kind := reflect.ValueOf(bean).Kind()
 	if kind == reflect.Map {
-		bodyMaps = bean.(BodyMap)
+		bm = bean.(BodyMap)
 		goto Verify
 	}
 
@@ -131,15 +131,15 @@ func VerifyWeChatSign(apiKey, signType string, bean interface{}) (ok bool, err e
 		return false, err
 	}
 
-	bodyMaps = make(BodyMap)
-	err = json.Unmarshal(bs, &bodyMaps)
+	bm = make(BodyMap)
+	err = json.Unmarshal(bs, &bm)
 	if err != nil {
 		return false, err
 	}
 Verify:
-	bodySign := bodyMaps.Get("sign")
-	bodyMaps.Remove("sign")
-	sign := getLocalSign(apiKey, signType, bodyMaps)
+	bodySign := bm.Get("sign")
+	bm.Remove("sign")
+	sign := getLocalSign(apiKey, signType, bm)
 	//fmt.Println("sign:", sign)
 	return sign == bodySign, nil
 }