package main import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/md5" "crypto/tls" "encoding/hex" "encoding/json" "fmt" "io/ioutil" "net/http" "time" "github.com/tidwall/gjson" ) type encBlockModer struct { block cipher.Block size int } type decBlockModer struct { block cipher.Block size int } //type ecbEncrypter ecb func newBlockModer(block cipher.Block, enc bool) cipher.BlockMode { if enc { return &encBlockModer{ block: block, size: block.BlockSize(), } } return &decBlockModer{ block: block, size: block.BlockSize(), } } func (p *encBlockModer) BlockSize() int { return p.size } func (p *encBlockModer) CryptBlocks(dst, src []byte) { srcLen := len(src) dstLen := len(dst) if srcLen%p.size != 0 || srcLen > dstLen { return } for len(src) > 0 { p.block.Encrypt(dst, src[:p.size]) src = src[p.size:] dst = dst[p.size:] } } func pkcs5Padding(src []byte, size int) []byte { padData := bytes.Repeat([]byte{byte(size - len(src)%size)}, size-len(src)%size) return append(src, padData...) } func pkcs5Trimming(src []byte) []byte { return src[:len(src)-int(src[len(src)-1])] } func AesEcbEncrypt(data []byte, key []byte) (string, error) { block, err := aes.NewCipher(key) if err != nil { return "", err } blockmoder := newBlockModer(block, true) data = pkcs5Padding(data, block.BlockSize()) crypted := make([]byte, len(data)) blockmoder.CryptBlocks(crypted, data) return hex.EncodeToString(crypted), nil } // func AES(src string, secret string) string { // bytes, _ := AesEncrypt(src, secret) // ret := hex.EncodeToString(bytes) // return ret // } func (p *decBlockModer) BlockSize() int { return p.size } func (p *decBlockModer) CryptBlocks(dst, src []byte) { if len(src)%p.size != 0 { return } if len(dst) < len(src) { return } for len(src) > 0 { p.block.Decrypt(dst, src[:p.size]) src = src[p.size:] dst = dst[p.size:] } } func AesEcbDecrpyt(src, key string) (string, error) { if src == "" { return "", nil } crypted, err := hex.DecodeString(src) if err != nil { return "", err } block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } blockModer := newBlockModer(block, false) plain := make([]byte, len(crypted)) blockModer.CryptBlocks(plain, crypted) plain = pkcs5Trimming(plain) return string(plain), nil } func getParamToUrl(url string, param map[string]string) string { if len(param) == 0 { return url } str := "" for k, v := range param { str = str + "&" + k + "=" + v } if str != "" { str = "?" + str[1:] } fmt.Printf("target url is:%s\n", url+str) return url + str } func getDataConten(param map[string]string, enc bool, secret string) map[string]string { pbytes, _ := json.Marshal(param) if !enc { return param } dataConten, err := AesEcbEncrypt(pbytes, []byte(secret)) if err != nil { panic(err) } m := map[string]string{ "encrypt_data": dataConten, } return m } func ApiVisitBySign(param map[string]string, enc bool, url string, secret string, appKey string) { client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, Timeout: 60 * time.Second, } fmt.Printf("appkey:%s\n", appKey) data := getDataConten(param, enc, secret) req, err := http.NewRequest("GET", getParamToUrl(url, data), nil) if err != nil { panic(err) } timestamp := time.Now().Unix() signText := fmt.Sprintf("%s%s%d", appKey, secret, timestamp) sign := MD5(signText) req.Header.Set("sign", sign) req.Header.Set("timestamp", fmt.Sprintf("%d", timestamp)) req.Header.Set("appkey", appKey) req.Header.Set("appsecret", secret) req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() res, err := ioutil.ReadAll(resp.Body) fmt.Printf("originRes:%s\n", res) codeExist := gjson.GetBytes(res, "code").Exists() if !codeExist { fmt.Printf("failed: originResis %s\n", res) return } code := gjson.GetBytes(res, "code").Int() if code != 0 { msg := gjson.GetBytes(res, "msg").String() fmt.Printf("api error:%d,%s\n", code, msg) return } resdata := gjson.GetBytes(res, "data").String() if enc && resdata != "" { resdata, err = AesEcbDecrpyt(resdata, secret) if err != nil { panic(err) } } fmt.Printf("success data is:%s\n", resdata) return } func ApiVisitByToken(param map[string]string, enc bool, token string, url string, secret string) { client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, Timeout: 60 * time.Second, } data := getDataConten(param, enc, secret) req, err := http.NewRequest("GET", getParamToUrl(url, data), nil) if err != nil { panic(err) } req.Header.Set("token", token) req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() res, err := ioutil.ReadAll(resp.Body) fmt.Printf("originRes:%s\n", res) codeExist := gjson.GetBytes(res, "code").Exists() if !codeExist { fmt.Printf("failed: originResis %s\n", res) return } code := gjson.GetBytes(res, "code").Int() if code != 0 { msg := gjson.GetBytes(res, "msg").String() fmt.Printf("api error:%d,%s\n", code, msg) return } resdata := gjson.GetBytes(res, "data").String() if enc && resdata != "" { resdata, err = AesEcbDecrpyt(resdata, secret) if err != nil { panic(err) } } fmt.Printf("success data is:%s\n", resdata) return } func tokenGet(tokenUrl string, user string, password string) string { m := map[string]string{ "user": user, "password": password, } transport := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{ Transport: transport, Timeout: 30 * time.Second, } req, err := http.NewRequest("GET", getParamToUrl(tokenUrl, m), nil) if err != nil { fmt.Printf("token get failed:%v\n", err) return "" } resp, err := client.Do(req) if err != nil { fmt.Printf("token get failed2:%v\n", err) return "" } defer resp.Body.Close() if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNotFound { fmt.Printf("token get failed3:%v\n", resp.StatusCode) return "" } result, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("token get failed4:%v\n", err) return "" } fmt.Printf("token:%s\n", result) token := gjson.GetBytes(result, "token").String() return token } func MD5(text string) string { h := md5.New() h.Write([]byte(text)) return hex.EncodeToString(h.Sum(nil)) } func main() { var ( // api 用户名 user = "529db83441acff61a054eba562185515" // api 密码 password = "DMh7lbyv" // 加密密钥 secret = "1749f2a7019db090ca7c9cc69e64033c" // token url tokenUrl = "http://127.0.0.1:41002/api/v1/token" // 接口url apiUrl = "http://127.0.0.1:41002/api/v1/query/test_api" // 参数 params = map[string]string{ "chepai": "川A814A1", } // 是否加密 crypt = false ) token := tokenGet(tokenUrl, user, password) if token == "" { fmt.Printf("token is empty\n") return } //ApiVisitByToken(params, crypt, token, apiUrl, secret) ApiVisitBySign(params, crypt, apiUrl, secret, user) }