GenSignature.go 3.74 KB
Newer Older
Ford committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"sort"
	"strings"
)

const (
	REQ_ACCESS_POP_TIMESTRAP = "access-pop-timestrap"
	REQ_ACCESS_POP_NONCESTR  = "access-pop-noncestr"
	REQ_ACCESS_POP_SIGNATURE = "access-pop-signature"
	REQ_ACCESS_POP_TOKEN     = "access-pop-token"
	HMAC_SHA256_ALGORITHM    = "HmacSHA256"
)

func main() {
	// 示例数据
	data := map[string]string{
		REQ_ACCESS_POP_TOKEN:     "4fb818df-af9e-4590-868f-52a6647cb91b9a6a7474-5891-4468-84fb-ccd0beef91a5",
		REQ_ACCESS_POP_TIMESTRAP: "cdd08ede-b836-44d2-8c10-b6abc0ac57aa",
		REQ_ACCESS_POP_NONCESTR:  "abcabcabcabcabc1",
	}

	// 获取当前时间戳
	//timestrap := time.Now().UnixNano() / int64(time.Millisecond)

	// 对数据进行排序
	keys := make([]string, 0, len(data))
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	var sortedData []string
	for _, k := range keys {
		sortedData = append(sortedData, fmt.Sprintf("%s=%s", k, data[k]))
	}

	// 拼接数据
	//signStr := fmt.Sprintf("%d\n%s\n%s\n%s", timestrap, strings.Join(sortedData, "\n"), REQ_ACCESS_POP_TOKEN, "cdd08ede-b836-44d2-8c10-b6abc0ac57aa")	signStr := fmt.Sprintf("%d\n%s\n%s\n%s", timestrap, strings.Join(sortedData, "\n"), REQ_ACCESS_POP_TOKEN, "cdd08ede-b836-44d2-8c10-b6abc0ac57aa")
	signStr := fmt.Sprintf("%d\n%s\n%s\n%s", REQ_ACCESS_POP_TIMESTRAP, strings.Join(sortedData, "\n"), REQ_ACCESS_POP_TOKEN, "cdd08ede-b836-44d2-8c10-b6abc0ac57aa")
	// 计算 HMAC-SHA256
	key := []byte("cdd08ede-b836-44d2-8c10-b6abc0ac57aa")
	h := hmac.New(sha256.New, key)
	h.Write([]byte(signStr))
	signature := hex.EncodeToString(h.Sum(nil))

	// 打印签名结果
	fmt.Println(signature)
}

func chkSignature(accessToken string, timestrap string, nonceStr string, signature string, signatureKey string) bool {
	treeMap := map[string]string{
		REQ_ACCESS_POP_TOKEN:     accessToken,
		REQ_ACCESS_POP_TIMESTRAP: timestrap,
		REQ_ACCESS_POP_NONCESTR:  nonceStr,
	}

	// 对数据进行排序
	keys := make([]string, 0, len(treeMap))
	for k := range treeMap {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	var sortedData []string
	for _, k := range keys {
		sortedData = append(sortedData, fmt.Sprintf("%s=%s", k, treeMap[k]))
	}

	// 拼接数据
	signStr := fmt.Sprintf("%s\n%s\n%s\n%s", accessToken, timestrap, nonceStr, signatureKey)

	// 计算 HMAC-SHA256
	key := []byte(signatureKey)
	h := hmac.New(sha256.New, key)
	h.Write([]byte(signStr))
	sysSignature := hex.EncodeToString(h.Sum(nil))

	if sysSignature != signature {
		log.Printf("签名不一致!%s -> %s", sysSignature, signature)
		return false
	}

	return true
}

func getObjectMd5Value(obj interface{}) string {
	bytes, err := json.Marshal(obj)
	if err != nil {
		log.Printf("json.Marshal error: %v", err)
		return ""
	}

	h := sha256.New()
	h.Write(bytes)

	return hex.EncodeToString(h.Sum(nil))
}

func postJson(url string, data interface{}, headers http.Header) ([]byte, error) {
	bytesData, err := json.Marshal(data)
	if err != nil {
		return nil, fmt.Errorf("json.Marshal error: %v", err)
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(bytesData))
	if err != nil {
		return nil, fmt.Errorf("http.NewRequest error: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")
	for k, v := range headers {
		req.Header[k] = v
	}

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("client.Do error: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("ioutil.ReadAll error: %v", err)
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("response status code not OK: %d, response body: %s", resp.StatusCode, string(body))
	}

	return body, nil
}