From 3231584ea1c215f5a9f9cf704df5e368d703db4c Mon Sep 17 00:00:00 2001 From: suyl <770236076@qq.com> Date: Tue, 17 Aug 2021 14:13:24 +0800 Subject: [PATCH] aa --- platformapi/dingdingapi/callback.go | 115 +++++++++++++++++++---- platformapi/jdshopapi/store_page_test.go | 12 ++- 2 files changed, 109 insertions(+), 18 deletions(-) diff --git a/platformapi/dingdingapi/callback.go b/platformapi/dingdingapi/callback.go index a81af435..d93e3c17 100644 --- a/platformapi/dingdingapi/callback.go +++ b/platformapi/dingdingapi/callback.go @@ -2,6 +2,8 @@ package dingdingapi import ( "bytes" + "crypto/aes" + "crypto/cipher" "crypto/sha1" "encoding/base64" "encoding/binary" @@ -37,9 +39,16 @@ type CallbackResponse struct { Encrypt string `json:"encrypt"` } +type DingTalkCrypto struct { + Token string + EncodingAESKey string + SuiteKey string + BKey []byte + Block cipher.Block +} + func (a *API) Err2CallbackResponse(err error) *CallbackResponse { if err == nil { - fmt.Println("111111111111111111111111") return a.PackCallbackResult(SuccessResponse) } return a.PackCallbackResult(err.Error()) @@ -109,20 +118,21 @@ func (a *API) Encrypt(msg string) (encryptedMsg string, err error) { return encryptedMsg, err } -func (a *API) Decrypt(msg string) (decryptedMsg string, err error) { - binMsg, err := base64.StdEncoding.DecodeString(msg) - if err == nil { - aesKey := a.GetCallbackAESKey() - binResult, err2 := utils.AESCBCDecpryt(binMsg, aesKey, aesKey[:16]) - if err = err2; err == nil { - var msgLen int32 - if err = binary.Read(bytes.NewBuffer(binResult[16:]), binary.BigEndian, &msgLen); err == nil { - // baseapi.SugarLogger.Debug(msgLen) - decryptedMsg = string(binResult[16+4 : 16+4+msgLen]) - } - } - } - return decryptedMsg, err +func (a *API) Decrypt(sign, timestr, nonce, msg string) (decryptedMsg string, err error) { + //binMsg, err := base64.StdEncoding.DecodeString(msg) + //if err == nil { + // aesKey := a.GetCallbackAESKey() + // binResult, err2 := utils.AESCBCDecpryt(binMsg, aesKey, aesKey[:16]) + // if err = err2; err == nil { + // var msgLen int32 + // if err = binary.Read(bytes.NewBuffer(binResult[16:]), binary.BigEndian, &msgLen); err == nil { + // // baseapi.SugarLogger.Debug(msgLen) + // decryptedMsg = string(binResult[16+4 : 16+4+msgLen]) + // } + // } + //} + c := NewDingTalkCrypto(a.GetCallbackToken(), string(a.GetCallbackAESKey()), a.corpID) + return c.GetDecryptMsg(sign, timestr, nonce, msg) } func (a *API) RegisterCallback(callbackTagList []string, token, aesKey, urlStr string) (err error) { @@ -208,7 +218,7 @@ func (a *API) GetCallbackMsg(formMap map[string]interface{}, bodyData []byte) (m err = errors.New("sign not match") } else { var descryptMsg string - if descryptMsg, err = a.Decrypt(encrypt); err == nil { + if descryptMsg, err = a.Decrypt(formMap["signature"].(string), formMap["timestamp"].(string), formMap["nonce"].(string), encrypt); err == nil { baseapi.SugarLogger.Debugf("dingding GetCallbackMsg descryptMsg:%s", descryptMsg) err = utils.UnmarshalUseNumber([]byte(descryptMsg), &msgMap) } @@ -217,3 +227,76 @@ func (a *API) GetCallbackMsg(formMap map[string]interface{}, bodyData []byte) (m } return nil, a.Err2CallbackResponse(err) } + +func NewDingTalkCrypto(token, encodingAESKey, suiteKey string) *DingTalkCrypto { + bkey, _ := base64.StdEncoding.DecodeString(encodingAESKey + "=") + block, _ := aes.NewCipher(bkey) + c := &DingTalkCrypto{ + Token: token, + EncodingAESKey: encodingAESKey, + SuiteKey: suiteKey, + BKey: bkey, + Block: block, + } + return c +} +func (c *DingTalkCrypto) GetDecryptMsg(signature, timestamp, nonce, secretMsg string) (string, error) { + if !c.VerificationSignature(c.Token, timestamp, nonce, secretMsg, signature) { + return "", errors.New("ERROR: 签名不匹配") + } + decode, err := base64.StdEncoding.DecodeString(secretMsg) + if err != nil { + return "", err + } + if len(decode) < aes.BlockSize { + return "", errors.New("ERROR: 密文太短") + } + blockMode := cipher.NewCBCDecrypter(c.Block, c.BKey[:c.Block.BlockSize()]) + plantText := make([]byte, len(decode)) + blockMode.CryptBlocks(plantText, decode) + plantText = pkCS7UnPadding(plantText) + size := binary.BigEndian.Uint32(plantText[16:20]) + plantText = plantText[20:] + corpID := plantText[size:] + if string(corpID) != c.SuiteKey { + return "", errors.New("ERROR: CorpID匹配不正确") + } + return string(plantText[:size]), nil +} + +// 数据签名 +func (c *DingTalkCrypto) CreateSignature(token, timestamp, nonce, msg string) string { + params := make([]string, 0) + params = append(params, token) + params = append(params, timestamp) + params = append(params, nonce) + params = append(params, msg) + sort.Strings(params) + return sha1Sign(strings.Join(params, "")) +} + +func sha1Sign(s string) string { + h := sha1.New() + h.Write([]byte(s)) + bs := h.Sum(nil) + return fmt.Sprintf("%x", bs) +} + +// 验证数据签名 +func (c *DingTalkCrypto) VerificationSignature(token, timestamp, nonce, msg, sigture string) bool { + return c.CreateSignature(token, timestamp, nonce, msg) == sigture +} + +// 解密补位 +func pkCS7UnPadding(plantText []byte) []byte { + length := len(plantText) + unpadding := int(plantText[length-1]) + return plantText[:(length - unpadding)] +} + +// 加密补位 +func pkCS7Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} diff --git a/platformapi/jdshopapi/store_page_test.go b/platformapi/jdshopapi/store_page_test.go index 7668723d..41e800b6 100644 --- a/platformapi/jdshopapi/store_page_test.go +++ b/platformapi/jdshopapi/store_page_test.go @@ -226,8 +226,16 @@ func TestUpdateDeliveryPromise(t *testing.T) { } func TestUploadImageNew(t *testing.T) { - s := "PLLPLA" - fmt.Println(checkRecord(s)) + str := "WHfuf4puh+swj/C6pp/a5suqY40fuzr78qn2RD3gE5bDW+4g4N+EFdwygdfmgy8P0VFe8hlCfPGR0MpqrBrSRpKy7e3SW93C3uKaCWbuZIQpiBGmy1bgOMgWxXIildIp" + data, err := base64.StdEncoding.DecodeString(str) + if err != nil { + fmt.Println("err1", err) + } + result, err := Decrypt(data, []byte("9d1e1d474ab4170211e279fadcc7647ec19fb54f"), []byte("EjTgnEa377fEcgzlQUbcgTzxPNznRjpOuSPgQAwv9aA")[:16]) + if err != nil { + fmt.Println("err2", err) + } + fmt.Println(string(result)) } func checkRecord(s string) bool {