Skip to content

Instantly share code, notes, and snippets.

@turret-io
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turret-io/5925a5f142b0b7a0ff55 to your computer and use it in GitHub Desktop.
Save turret-io/5925a5f142b0b7a0ff55 to your computer and use it in GitHub Desktop.
Verify HMAC in Go
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")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment