package signature import ( "crypto/sha256" "fmt" "net/url" "sort" "strings" ) // BuildStringToSign 构造待签字符串 // StringToSign = METHOD\nPATH\nCANONICAL_QUERY\nBODY_SHA256\nX-App-Id\nX-Timestamp\nX-Nonce func BuildStringToSign(method, path, rawQuery string, body []byte, appId, timestamp, nonce string) string { canonical := canonicalQuery(rawQuery) bodyHash := sha256Hex(body) parts := []string{ strings.ToUpper(method), path, canonical, bodyHash, appId, timestamp, nonce, } return strings.Join(parts, "\n") } func canonicalQuery(rawQuery string) string { if rawQuery == "" { return "" } values, err := url.ParseQuery(rawQuery) if err != nil { return rawQuery } keys := make([]string, 0, len(values)) for k := range values { keys = append(keys, k) } sort.Strings(keys) parts := make([]string, 0, len(keys)) for _, k := range keys { parts = append(parts, fmt.Sprintf("%s=%s", k, values.Get(k))) } return strings.Join(parts, "&") } func sha256Hex(data []byte) string { h := sha256.Sum256(data) return fmt.Sprintf("%x", h) }