mirror of https://github.com/golang-jwt/jwt.git
cmd: add handling of HS keys
Signed-off-by: Paul Greenberg <greenpau@outlook.com>
This commit is contained in:
parent
d0c0939ff8
commit
c6a6a5f45b
|
@ -1,19 +1,97 @@
|
|||
`jwt` command-line tool
|
||||
=======================
|
||||
# `jwt` command-line tool
|
||||
|
||||
This is a simple tool to sign, verify and show JSON Web Tokens from
|
||||
the command line.
|
||||
|
||||
## Getting Started
|
||||
|
||||
The following will create and sign a token, then verify it and output the original claims:
|
||||
|
||||
```bash
|
||||
echo {\"foo\":\"bar\"} | ./jwt -key ../../test/sample_key -alg RS256 -sign - | ./jwt -key ../../test/sample_key.pub -alg RS256 -verify -
|
||||
```
|
||||
|
||||
Key files should be in PEM format. Other formats are not supported by this tool.
|
||||
|
||||
To simply display a token, use:
|
||||
|
||||
```bash
|
||||
echo $JWT | ./jwt -show -
|
||||
```
|
||||
|
||||
You can install this tool with the following command:
|
||||
|
||||
```bash
|
||||
go install github.com/golang-jwt/jwt/v4/cmd/jwt
|
||||
```
|
||||
|
||||
## Sign/Verify with Shared Secret
|
||||
|
||||
First, create a JSON document with token payload, e.g. `~/experimental/jwt/data`.
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "jsmith@foo.bar",
|
||||
"aud": "foo.bar",
|
||||
"exp": 2559489932,
|
||||
"iat": 1612805132,
|
||||
"iss": "foo.bar",
|
||||
"sub": "jsmith"
|
||||
}
|
||||
```
|
||||
|
||||
Then, create a file with shared secret key, e.g. `~/experimental/jwt/token.key`.
|
||||
|
||||
```
|
||||
foobarbaz
|
||||
```
|
||||
|
||||
Next, sign the token:
|
||||
|
||||
```bash
|
||||
./jwt -key ~/experimental/jwt/token.key -alg HS512 -sign ~/experimental/jwt/data > ~/experimental/jwt/token.jwt
|
||||
```
|
||||
|
||||
After that, review the token:
|
||||
|
||||
```bash
|
||||
./jwt -show ~/experimental/jwt/token.jwt
|
||||
```
|
||||
|
||||
The expected output follows:
|
||||
|
||||
```
|
||||
Header:
|
||||
{
|
||||
"alg": "HS512",
|
||||
"typ": "JWT"
|
||||
}
|
||||
Claims:
|
||||
{
|
||||
"aud": "foo.bar",
|
||||
"email": "jsmith@foo.bar",
|
||||
"exp": 2559489932,
|
||||
"iat": 1612805132,
|
||||
"iss": "foo.bar",
|
||||
"sub": "jsmith"
|
||||
}
|
||||
```
|
||||
|
||||
Subsequently, validate the token:
|
||||
|
||||
```bash
|
||||
./jwt -key ~/experimental/jwt/token.key -alg HS512 -verify ~/experimental/jwt/token.jwt
|
||||
```
|
||||
|
||||
The expected output follows:
|
||||
|
||||
```
|
||||
{
|
||||
"aud": "foo.bar",
|
||||
"email": "jsmith@foo.bar",
|
||||
"exp": 2559489932,
|
||||
"iat": 1612805132,
|
||||
"iss": "foo.bar",
|
||||
"sub": "jsmith"
|
||||
}
|
||||
```
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
@ -16,6 +17,7 @@ import (
|
|||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
@ -142,6 +144,8 @@ func verifyToken() error {
|
|||
return jwt.ParseRSAPublicKeyFromPEM(data)
|
||||
} else if isEd() {
|
||||
return jwt.ParseEdPublicKeyFromPEM(data)
|
||||
} else if isHs() {
|
||||
return parseHSKey(data)
|
||||
}
|
||||
return data, nil
|
||||
})
|
||||
|
@ -196,9 +200,19 @@ func signToken() error {
|
|||
|
||||
// get the key
|
||||
var key interface{}
|
||||
if isNone() {
|
||||
switch {
|
||||
case isNone():
|
||||
key = jwt.UnsafeAllowNoneSignatureType
|
||||
} else {
|
||||
case isHs():
|
||||
kb, err := loadData(*flagKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't read key: %w", err)
|
||||
}
|
||||
key, err = parseHSKey(kb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
key, err = loadData(*flagKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't read key: %w", err)
|
||||
|
@ -292,6 +306,10 @@ func showToken() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func isHs() bool {
|
||||
return strings.HasPrefix(*flagAlg, "HS")
|
||||
}
|
||||
|
||||
func isEs() bool {
|
||||
return strings.HasPrefix(*flagAlg, "ES")
|
||||
}
|
||||
|
@ -342,3 +360,17 @@ func (l ArgList) Set(arg string) error {
|
|||
l[parts[0]] = parts[1]
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseHSKey(b []byte) ([]byte, error) {
|
||||
if len(b) == 0 {
|
||||
return nil, fmt.Errorf("shared key is empty")
|
||||
}
|
||||
f := func(c rune) bool {
|
||||
return unicode.IsSpace(c)
|
||||
}
|
||||
i := bytes.IndexFunc(b, f)
|
||||
if i < 0 {
|
||||
return b, nil
|
||||
}
|
||||
return b[:i], nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue