1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- package initdata
- import (
- "crypto/hmac"
- "crypto/sha256"
- "encoding/hex"
- "net/url"
- "sort"
- "strconv"
- "strings"
- "time"
- )
- // Sign signs passed payload using specified key. Function removes such
- // technical parameters as "hash" and "auth_date".
- func Sign(payload map[string]string, key string, authDate time.Time) string {
- pairs := make([]string, 0, len(payload)+1)
- // Extract all key-value pairs and add them to pairs slice.
- for k, v := range payload {
- // Skip technical fields.
- if k == "hash" || k == "auth_date" {
- continue
- }
- // Append new pair.
- pairs = append(pairs, k+"="+v)
- }
- // Append sign date.
- pairs = append(pairs, "auth_date="+strconv.FormatInt(authDate.Unix(), 10))
- // According to docs, we sort all the pairs in alphabetical order.
- sort.Strings(pairs)
- // Perform signing.
- return sign(strings.Join(pairs, "\n"), key)
- }
- // SignQueryString signs passed query string.
- func SignQueryString(qs, key string, authDate time.Time) (string, error) {
- // Parse query string.
- qp, err := url.ParseQuery(qs)
- if err != nil {
- return "", err
- }
- // Convert query params to map[string]string.
- m := make(map[string]string, len(qp))
- for k, v := range qp {
- m[k] = v[0]
- }
- return Sign(m, key, authDate), nil
- }
- // Performs payload subscription. Payload itself slice of key-value pairs
- // joined with "\n".
- func sign(payload, key string) string {
- skHmac := hmac.New(sha256.New, []byte("WebAppData"))
- skHmac.Write([]byte(key))
- impHmac := hmac.New(sha256.New, skHmac.Sum(nil))
- impHmac.Write([]byte(payload))
- return hex.EncodeToString(impHmac.Sum(nil))
- }
|