itsdangerous is a Go package which provides
- Methods to create and verify MAC signatures of data
- Ability to add timestamps to signed tokens and use custom epoch if needed.
- BLAKE3 signatures and Base58 time encoding provides outstanding performance and security.
- A very simple to use API with good documentation and 100% test coverage.
- Various helper methods for parsing tokens
BLAKE3 support is provided by blake3.
Go get the package in the usual way:
go get -u github.com/tsawler/itsdangerous
A simple example:
package main
import (
"fmt"
"github.com/tsawler/itsdangerous"
"log"
"time"
)
func main() {
// Create a secret; typically, make this 32 characters long.
var secret = []byte("some-very-good-secret")
// The data to be signed.
var data = []byte("https://example.com?id=10")
// Create a new instance of itsdangerous.
s := itsdangerous.New(secret)
// Sign the data; we get back a byte array with the signature appended.
token := s.Sign(data)
// Unsign the token to verify it. If successful the data portion of the
// token is returned. If unsuccessful then d will be nil, and an error
// is returned.
d, err := s.Unsign(token)
if err != nil {
// The signature is not valid. The token was tampered with, forged, or maybe it's
// not even a token at all. It's not safe to use it.
log.Println("Invalid signature error:", err)
} else {
// The signature is valid, so it is safe to use the data.
fmt.Println("Unsigned:", string(d))
fmt.Println("Signed:", string(token))
fmt.Println("Valid signature!")
}
// Create a new signer, this time with a timestamp.
s2 := itsdangerous.New(secret, itsdangerous.Timestamp)
token = s2.Sign(data)
// print out new signed data
fmt.Println("Signed with timestamp:", string(token))
// Parse the token.
ts := s2.Parse(token)
// The token should be not expired at this point.
if time.Since(ts.Timestamp) < time.Second {
fmt.Println("Token with timestamp has not expired!")
}
// Wait two seconds to expire the token.
time.Sleep(2 * time.Second)
// The token should be expired at this point.
if time.Since(ts.Timestamp) > time.Second {
fmt.Println("Token with timestamp is expired!")
}
}
The output of this program is something like:
tcs@Grendel example-itsdangerous % go run .
Unsigned: https://example.com?id=10
Signed: https://example.com?id=10.eoaZ-lDxxuZ-BK5PFmbZlVps0Htqi6NILs0HR47Dvs0
Valid signature!
Signed with timestamp: https://example.com?id=10.3yzzW5.fuoQr38zm2rQdbwFdXtU1BOeRmp1HDmyNhOM3ZTXfCY
Token with timestamp has not expired!
Token with timestamp is expired!
To run all tests, execute this command:
go test -v .
To run benchmarks, execute this command:
go test -v -bench=.
This code is an updated version of go-alone. Major changes include updating to use go modules, and moving from BLAKE2b to BLAKE3.