Skip to content

Commit 42ae8ae

Browse files
committed
version 1.0.0
1 parent 14b6a6e commit 42ae8ae

21 files changed

+1457
-168
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
.task
22
dist
33
log
4-
jwt-cli
4+
jwt-cli
5+
*pem
6+
*.pub
7+
*.key

README.md

+82-4
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ Available Commands:
1212
completion Generate the autocompletion script for the specified shell
1313
decode decode JWT token
1414
encode encode JWT token
15+
genkeys print commands example to generate keys for ES256, ES384, ES512, RS256, RS384, RS512
1516
help Help about any command
16-
methods print list of signing methods
1717
version print version of jwt-cli
1818
1919
Flags:
20-
-h, --help help for jwt-cli
21-
--m string Signing Method
22-
--s string JWT secret
20+
-h, --help help for jwt-cli
2321
2422
Use "jwt-cli [command] --help" for more information about a command.
2523
```
@@ -29,6 +27,12 @@ Supported methods are actually:
2927
* HS256
3028
* HS384
3129
* HS512
30+
* ES256
31+
* ES384
32+
* ES512
33+
* RS256
34+
* RS384
35+
* RS512
3236

3337

3438
# Install
@@ -45,6 +49,36 @@ brew tap sgaunet/tools
4549
brew install jwt-cli
4650
```
4751

52+
## Option 3: Docker image
53+
54+
Possibility to copy the binary by using the docker image
55+
56+
```
57+
FROM sgaunet/jwt-cli:latest as jwtcli
58+
59+
FROM ....
60+
COPY --from jwtcli /jwt-cli /usr/bin/jwt-cli
61+
```
62+
63+
# Getting started
64+
65+
Quite easy, this tool will help you to encode/decode JWT tokens.
66+
67+
```
68+
# encode
69+
$ jwt-cli encode hs512 --p '{ "email": "[email protected]" }' --s "myAwesomeSecret"
70+
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im15ZW1haWxAbWUuY29tIn0.SE0u1AWrDTHv67PnUALZl8VQ-7rnSXBNDTCVT_Dj12FStO6hL0ak0i4imcUHpWBEh-c5oSc-H90prGQ0oZx6ng
71+
# try to decode with a wrong secret
72+
$ jwt-cli decode hs512 --s "wrong secret" --t "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im15ZW1haWxAbWUuY29tIn0.SE0u1AWrDTHv67PnUALZl8VQ-7rnSXBNDTCVT_Dj12FStO6hL0ak0i4imcUHpWBEh-c5oSc-H90prGQ0oZx6ng"
73+
signature is invalid
74+
# decode with the good secret
75+
$ jwt-cli decode hs512 --s "myAwesomeSecret" --t "eyJhbGciOiJIUzUxMiIsInR
76+
5cCI6IkpXVCJ9.eyJlbWFpbCI6Im15ZW1haWxAbWUuY29tIn0.SE0u1AWrDTHv67PnUALZl8VQ-7rnSXBNDTCVT_Dj12FStO6hL0ak0i4imcUHpWBEh-c5oSc-H90prGQ0oZx6ng"
77+
{
78+
"email": "[email protected]"
79+
}
80+
```
81+
4882
# Development
4983

5084
This project is using :
@@ -58,3 +92,47 @@ This project is using :
5892

5993
The docker image is only created to simplify the copy of jwt-cli in another docker image.
6094

95+
96+
# Create keys
97+
98+
## RS256
99+
100+
```
101+
ssh-keygen -t rsa -b 4096 -E SHA256 -m PEM -P "" -f RS256.key
102+
openssl rsa -in RS256.key -pubout -outform PEM -out RS256.key.pub
103+
```
104+
105+
## RS384
106+
107+
```
108+
ssh-keygen -t rsa -b 4096 -E SHA384 -m PEM -P "" -f RS384.key
109+
openssl rsa -in RS384.key -pubout -outform PEM -out RS384.key.pub
110+
```
111+
112+
## RS512
113+
114+
```
115+
ssh-keygen -t rsa -b 4096 -E SHA512 -m PEM -P "" -f RS512.key
116+
openssl rsa -in RS512.key -pubout -outform PEM -out RS512.key.pub
117+
```
118+
119+
## ES256
120+
121+
```
122+
openssl ecparam -genkey -name prime256v1 -noout -out ecdsa-p256-private.pem
123+
openssl ec -in ecdsa-p256-private.pem -pubout -out ecdsa-p256-public.pem
124+
```
125+
126+
## ES384
127+
128+
```
129+
openssl ecparam -name secp384r1 -genkey -noout -out jwtES384key.pem
130+
openssl ec -in jwtES384key.pem -pubout -out jwtES384pubkey.pem
131+
```
132+
133+
## ES512
134+
135+
```
136+
openssl ecparam -genkey -name secp521r1 -noout -out ecdsa-p521-private.pem
137+
openssl ec -in ecdsa-p521-private.pem -pubout -out ecdsa-p521-public.pem
138+
```

Taskfile.yml

+14
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,24 @@ tasks:
1313
generates:
1414
- "{{.BINFILE}}"
1515

16+
install:
17+
cmds:
18+
- go get golang.org/x/tools/cmd/godoc
19+
20+
doc:
21+
cmds:
22+
- echo http://localhost:6060
23+
- godoc -http=:6060
24+
1625
snapshot:
1726
cmds:
1827
- GITLAB_TOKEN="" goreleaser --clean --snapshot
1928

2029
release:
2130
cmds:
2231
- GITLAB_TOKEN="" goreleaser --clean
32+
33+
tests:
34+
dir: tests
35+
cmds:
36+
- venom run testsuite.yml --output-dir="log" --stop-on-failure

cmd/decode-es.go

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/sgaunet/jwt-cli/pkg/cryptojwt"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
var decodeES256Cmd = &cobra.Command{
12+
Use: "es256",
13+
Short: "decode JWT token",
14+
Long: `decode JWT token`,
15+
Run: func(cmd *cobra.Command, args []string) {
16+
var (
17+
j cryptojwt.Decoder
18+
err error
19+
)
20+
if privateKeyFile == "" && publicKeyFile == "" {
21+
fmt.Println("private key file or public key file is mandatory")
22+
fmt.Println(cmd.UsageString())
23+
os.Exit(1)
24+
}
25+
if token == "" {
26+
fmt.Println("token is mandatory")
27+
fmt.Println(cmd.UsageString())
28+
os.Exit(1)
29+
}
30+
if publicKeyFile != "" {
31+
j = cryptojwt.NewES256DecoderWithPublicKeyFile(publicKeyFile)
32+
} else {
33+
j = cryptojwt.NewES256DecoderWithPrivateKeyFile(privateKeyFile)
34+
}
35+
if err != nil {
36+
fmt.Println(err)
37+
os.Exit(1)
38+
}
39+
t, err := j.Decode(token)
40+
if err != nil {
41+
fmt.Println(err)
42+
os.Exit(1)
43+
}
44+
fmt.Println(t)
45+
},
46+
}
47+
48+
var decodeES384Cmd = &cobra.Command{
49+
Use: "es384",
50+
Short: "decode es384 JWT token",
51+
Long: `decode es384 JWT token`,
52+
Run: func(cmd *cobra.Command, args []string) {
53+
var j cryptojwt.Decoder
54+
if privateKeyFile == "" && publicKeyFile == "" {
55+
fmt.Println("private key file or public key file is mandatory")
56+
fmt.Println(cmd.UsageString())
57+
os.Exit(1)
58+
}
59+
if token == "" {
60+
fmt.Println("token is mandatory")
61+
fmt.Println(cmd.UsageString())
62+
os.Exit(1)
63+
}
64+
if publicKeyFile != "" {
65+
j = cryptojwt.NewES384DecoderWithPublicKeyFile(publicKeyFile)
66+
} else {
67+
j = cryptojwt.NewES384DecoderWithPrivateKeyFile(privateKeyFile)
68+
}
69+
t, err := j.Decode(token)
70+
if err != nil {
71+
fmt.Println(err)
72+
os.Exit(1)
73+
}
74+
fmt.Println(t)
75+
},
76+
}
77+
78+
var decodeES512Cmd = &cobra.Command{
79+
Use: "es512",
80+
Short: "decode es512 JWT token",
81+
Long: `decode es512 JWT token`,
82+
Run: func(cmd *cobra.Command, args []string) {
83+
var j cryptojwt.Decoder
84+
if privateKeyFile == "" && publicKeyFile == "" {
85+
fmt.Println("private key file or public key file is mandatory")
86+
fmt.Println(cmd.UsageString())
87+
os.Exit(1)
88+
}
89+
if token == "" {
90+
fmt.Println("token is mandatory")
91+
fmt.Println(cmd.UsageString())
92+
os.Exit(1)
93+
}
94+
if publicKeyFile != "" {
95+
j = cryptojwt.NewES512DecoderWithPublicKeyFile(publicKeyFile)
96+
} else {
97+
j = cryptojwt.NewES512DecoderWithPrivateKeyFile(privateKeyFile)
98+
}
99+
t, err := j.Decode(token)
100+
if err != nil {
101+
fmt.Println(err)
102+
os.Exit(1)
103+
}
104+
fmt.Println(t)
105+
},
106+
}

cmd/decode-hs.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/sgaunet/jwt-cli/pkg/cryptojwt"
8+
9+
"github.com/spf13/cobra"
10+
)
11+
12+
// encodeCmd represents the encode command
13+
var decodeHS256Cmd = &cobra.Command{
14+
Use: "hs256",
15+
Short: "decode HS256 JWT token",
16+
Long: `decode HS256 JWT token`,
17+
Run: func(cmd *cobra.Command, args []string) {
18+
var err error
19+
if secret == "" {
20+
fmt.Println("secret is mandatory")
21+
fmt.Println(cmd.UsageString())
22+
os.Exit(1)
23+
}
24+
if token == "" {
25+
fmt.Println("token is mandatory")
26+
fmt.Println(cmd.UsageString())
27+
os.Exit(1)
28+
}
29+
j := cryptojwt.NewHS256Decoder([]byte(secret))
30+
t, err := j.Decode(token)
31+
if err != nil {
32+
fmt.Println(err)
33+
os.Exit(1)
34+
}
35+
fmt.Println(t)
36+
},
37+
}
38+
39+
var decodeHS384Cmd = &cobra.Command{
40+
Use: "hs384",
41+
Short: "decode HS384 JWT token",
42+
Long: `decode HS384 JWT token`,
43+
Run: func(cmd *cobra.Command, args []string) {
44+
var err error
45+
if secret == "" {
46+
fmt.Println("secret is mandatory")
47+
fmt.Println(cmd.UsageString())
48+
os.Exit(1)
49+
}
50+
if token == "" {
51+
fmt.Println("token is mandatory")
52+
fmt.Println(cmd.UsageString())
53+
os.Exit(1)
54+
}
55+
j := cryptojwt.NewHS384Decoder([]byte(secret))
56+
t, err := j.Decode(token)
57+
if err != nil {
58+
fmt.Println(err)
59+
os.Exit(1)
60+
}
61+
fmt.Println(t)
62+
},
63+
}
64+
65+
var decodeHS512Cmd = &cobra.Command{
66+
Use: "hs512",
67+
Short: "decode HS512 JWT token",
68+
Long: `decode HS512 JWT token`,
69+
Run: func(cmd *cobra.Command, args []string) {
70+
var err error
71+
if secret == "" {
72+
fmt.Println("secret is mandatory")
73+
fmt.Println(cmd.UsageString())
74+
os.Exit(1)
75+
}
76+
if token == "" {
77+
fmt.Println("token is mandatory")
78+
fmt.Println(cmd.UsageString())
79+
os.Exit(1)
80+
}
81+
j := cryptojwt.NewHS512Decoder([]byte(secret))
82+
t, err := j.Decode(token)
83+
if err != nil {
84+
fmt.Println(err)
85+
os.Exit(1)
86+
}
87+
fmt.Println(t)
88+
},
89+
}

0 commit comments

Comments
 (0)