package main import ( "crypto/hmac" "crypto/sha512" "encoding/base64" "encoding/json" "errors" "fmt" "net/url" "strconv" "time" ) const sharedSecret = "sup3rs3cr3t!!" func verifyString(stringToVerify []byte, signature []byte, sharedSecret []byte) bool { h := hmac.New(sha512.New, sharedSecret) h.Write(stringToVerify) calculated := h.Sum(nil) return hmac.Equal(calculated, signature) } func verifyTime(decodedJSON []byte) (map[string]string, error) { payload := make(map[string]string) err := json.Unmarshal(decodedJSON, &payload) if err != nil { return nil, err } time64, err := strconv.ParseInt(payload["timestamp"], 10, 64) if err != nil { return nil, err } if (time.Now().Unix() - time64) > 30 { return nil, errors.New("Timestamp is too far in the past") } return payload, nil } func main() { url, err := url.Parse("[QUERYSTRING]") if err != nil { panic(err) } decodedSignature, err := base64.URLEncoding.DecodeString(url.Query().Get("signature")) if err != nil { panic(err) } decodedJSON, err := base64.URLEncoding.DecodeString(url.Query().Get("data")) if err != nil { panic(err) } ok := verifyString(decodedJSON, decodedSignature, []byte(sharedSecret)) if ok { fmt.Println("Signature verified") payload, err := verifyTime(decodedJSON) if err != nil { panic(err) } fmt.Println("Payload verified") fmt.Println(payload) } else { fmt.Println("Invalid signature") } }