func doDec(signer jwt.Signer, in []byte) ([]byte, error) {
	t := UnstructuredToken{}
	if err := signer.Decode(bytes.TrimSpace(in), &t); err != nil {
		return nil, err
	}
	out, err := json.MarshalIndent(&t, "", "  ")
	if err != nil {
		return nil, err
	}
	return out, nil
}
doDec decodes in as a JWT.
package main
import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rsa"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"github.com/mattn/go-isatty"
	"github.com/kenshaw/jwt"
	"github.com/kenshaw/pemutil"
)
func main() {
	flagEnc := flag.Bool("enc", false, "encode token from json data provided from stdin, or via name=value pairs passed on the command line")
	flagDec := flag.Bool("dec", false, "decode and verify token read from stdin using the provided key data")
	flagKey := flag.String("k", "", "path to PEM-encoded file or JSON file containing key data")
	flagAlg := flag.String("alg", "", "override signing algorithm")
	flag.Parse()
	if err := run(*flagEnc, *flagDec, *flagKey, *flagAlg, flag.Args()); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}
func run(enc, dec bool, key, algType string, args []string) error {
	switch {
	case key == "":
		return errors.New("must supply a key file with -k")
	case len(args) > 0 && dec:
		return errors.New("unknown args passed for -dec")
	}
	var err error
	var in []byte
	if len(args) > 0 && enc {
		in, err = buildEncArgs(args)
	} else {
		in, err = ioutil.ReadAll(os.Stdin)
	}
	if err != nil {
		return err
	}
	pem, suggestedAlg, err := loadKeyData(key)
	if err != nil {
		return err
	}
	var alg jwt.Algorithm
	switch {
	case suggestedAlg != jwt.NONE:
		alg = suggestedAlg
	case algType != "":
		err = (&alg).UnmarshalText([]byte(algType))
	case dec:
		alg, err = jwt.PeekAlgorithm(in)
	default:
		alg, err = getAlgFromKeyData(pem)
	}
	if err != nil {
		return err
	}
	signer, err := alg.New(pem)
	if err != nil {
		return err
	}
	var out []byte
	switch {
	case dec:
		out, err = doDec(signer, in)
	case enc:
		out, err = doEnc(signer, in)
	default:
		return errors.New("please specify -enc or -dec")
	}
	if err != nil {
		return err
	}
	if isatty.IsTerminal(os.Stdout.Fd()) {
		out = append(out, '\n')
	}
	_, err = os.Stdout.Write(out)
	return err
}
func loadKeyData(path string) (pemutil.Store, jwt.Algorithm, error) {
	buf, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, jwt.NONE, err
	}
	v := make(map[string]interface{})
	if err = json.Unmarshal(buf, &v); err != nil {
		keyset, err := pemutil.LoadFile(path)
		if err != nil {
			return nil, jwt.NONE, err
		}
		return keyset, jwt.NONE, nil
	}
	keyset := pemutil.Store{}
	for _, val := range v {
		if str, ok := val.(string); ok {
			_ = keyset.Decode([]byte(str))
		}
	}
	keyset.AddPublicKeys()
	if len(keyset) < 1 {
		return nil, jwt.NONE, fmt.Errorf("could not find any PEM encoded keys in %s", path)
	}
	if bytes.Contains(buf, []byte("gserviceaccount.com")) {
		return keyset, jwt.RS256, nil
	}
	return keyset, jwt.NONE, nil
}
func getSuitableAlgFromCurve(curve elliptic.Curve) (jwt.Algorithm, error) {
	curveBitSize := curve.Params().BitSize
	keyLen := curveBitSize / 8
	if curveBitSize%8 > 0 {
		keyLen++
	}
	var alg jwt.Algorithm
	switch 2 * keyLen {
	case 64:
		alg = jwt.ES256
	case 96:
		alg = jwt.ES384
	case 132:
		alg = jwt.ES512
	default:
		return jwt.NONE, fmt.Errorf("invalid key length %d", keyLen)
	}
	return alg, nil
}
func getAlgFromKeyData(pem pemutil.Store) (jwt.Algorithm, error) {
	for _, v := range pem {
		switch k := v.(type) {
		case []byte:
			return jwt.HS512, nil
		case *ecdsa.PrivateKey:
			return getSuitableAlgFromCurve(k.Curve)
		case *ecdsa.PublicKey:
			return getSuitableAlgFromCurve(k.Curve)
		case *rsa.PrivateKey:
			return jwt.PS512, nil
		case *rsa.PublicKey:
			return jwt.PS512, nil
		}
	}
	return jwt.NONE, errors.New("cannot determine key type")
}
func buildEncArgs(args []string) ([]byte, error) {
	m := make(map[string]interface{})
	for _, arg := range args {
		a := strings.SplitN(arg, "=", 2)
		var val interface{}
		if len(a) == 1 {  
			val = true
		} else if u, err := strconv.ParseUint(a[1], 10, 64); err == nil {
			val = u
		} else if i, err := strconv.ParseInt(a[1], 10, 64); err == nil {
			val = i
		} else if f, err := strconv.ParseFloat(a[1], 64); err == nil {
			val = f
		} else if b, err := strconv.ParseBool(a[1]); err == nil {
			val = b
		} else if s, err := strconv.Unquote(a[1]); err == nil {
			val = s
		} else {  
			val = a[1]
		}
		m[a[0]] = val
	}
	return json.Marshal(m)
}
type UnstructuredToken struct {
	Header    map[string]interface{} `json:"header" jwt:"header"`
	Payload   map[string]interface{} `json:"payload" jwt:"payload"`
	Signature []byte                 `json:"signature" jwt:"signature"`
}