package thirdparty import ( "bytes" "encoding/base64" "encoding/hex" "encoding/json" "fmt" "gd_vehicle/common.in/utils" "go.uber.org/zap" "gd_vehicle/common.in/config" id2 "gd_vehicle/common.in/id" //"github.com/tidwall/gjson" "io/ioutil" "net/http" "time" "github.com/tjfoc/gmsm/sm4" ) // PKCSPadd填充算法 func PKCS7Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padText...) } func PKCS7UnPadding(origData []byte) []byte { length := len(origData) unPadding := int(origData[length-1]) return origData[:(length - unPadding)] } func SM4ECBBase64Encrypt(originalText string, key []byte) (string, error) { block, err := sm4.NewCipher(key) if err != nil { panic(err) } originalBytes := []byte(originalText) originalBytes = PKCS7Padding(originalBytes, block.BlockSize()) cipherArr := make([]byte, 0) cArr := make([]byte, 16) j := 0 for i := 0; i < len(originalBytes)/16; i++ { original := originalBytes[j : j+16] block.Encrypt(cArr, original) cipherArr = append(cipherArr, cArr...) j = j + 16 } base64Str := base64.StdEncoding.EncodeToString(cipherArr) return base64Str, nil } func SM4ECBBase64Decrypt(cipherText string) (string, error) { key, _ := hex.DecodeString(config.Conf.ThirdPart.CdbdSecret) cInArr, _ := base64.StdEncoding.DecodeString(cipherText) block, err := sm4.NewCipher(key) if err != nil { panic(err) } cipherArr := make([]byte, 0) cArr := make([]byte, 16) j := 0 for i := 0; i < len(cInArr)/16; i++ { original := cInArr[j : j+16] block.Decrypt(cArr, original) cipherArr = append(cipherArr, cArr...) j = j + 16 } originalText := string(PKCS7UnPadding(cipherArr)) return originalText, nil } func CdBdClientPost(api, code string, data map[string]string, httpTimeout int) (result []byte, err error) { defer func() { l.Info("thirdparty", zap.String("api", api), zap.String("request", utils.MarshalJsonString(data)), zap.String("response", utils.MarshalJsonString(result))) }() if httpTimeout == 0 { httpTimeout = 30 } key, _ := hex.DecodeString(config.Conf.ThirdPart.CdbdSecret) client := &http.Client{} client.Timeout = time.Duration(httpTimeout) * time.Second authorization, _ := id2.GetDistributedUniqueID() data["authorization"] = fmt.Sprintf("%d", authorization) //fmt.Println("data:", data) param := map[string]string{} rdata, _ := json.Marshal(data) //fmt.Println("rdata :", string(rdata), data) tmp, err := SM4ECBBase64Encrypt(string(rdata), key) if err != nil { fmt.Println("encoding failed :", tmp, err) } param["param"] = tmp requestData, _ := json.Marshal(param) //fmt.Println("request data :", string(requestData)) req, err := http.NewRequest("POST", api, bytes.NewBuffer(requestData)) if err != nil { return nil, err } timestamp := time.Now().UnixNano() / 1e6 id, _ := id2.GetDistributedUniqueID() header := map[string]string{} header["random"] = fmt.Sprintf("%d", id) header["timestamp"] = fmt.Sprintf("%d", timestamp) header["clientId"] = config.Conf.ThirdPart.CdbdClientId //"f830bebbec534450b22d2e766cb4cc36" header["code"] = code //"DPA12Y003R02310231-DSA12CDS0231" siginStr := "" for k, v := range header { tmp := k + "=" + v if siginStr == "" { siginStr = tmp } else { siginStr = siginStr + "&" + tmp } } sigin, _ := SM4ECBBase64Encrypt(siginStr, key) header["signature"] = sigin //fmt.Println("header :", header, siginStr) for k, v := range header { req.Header.Set(k, v) } req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("wrong status code: %d", resp.StatusCode) } defer resp.Body.Close() result, err = ioutil.ReadAll(resp.Body) return }