-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjwt.go
111 lines (95 loc) · 2.66 KB
/
jwt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"io/ioutil"
"time"
"github.com/lestrrat-go/jwx/jwk"
)
// 秘密鍵を読み込む
func readPrivateKey() (*rsa.PrivateKey, error) {
data, err := ioutil.ReadFile("private-key.pem")
if err != nil {
return nil, err
}
keyblock, _ := pem.Decode(data)
if keyblock == nil {
return nil, fmt.Errorf("invalid private key data")
}
if keyblock.Type != "RSA PRIVATE KEY" {
return nil, fmt.Errorf("invalid private key type : %s", keyblock.Type)
}
privateKey, err := x509.ParsePKCS1PrivateKey(keyblock.Bytes)
if err != nil {
return nil, err
}
return privateKey, nil
}
// "ヘッダー.ペイロード"を作成する
func makeHeaderPayload() string {
// ヘッダー
var header = []byte(`{"alg":"RS256","kid": "12345678","typ":"JWT"}`)
// ペイロード
var payload = Payload{
Iss: "https://oreore.oidc.com",
Azp: clientInfo.id,
Aud: clientInfo.id,
Sub: user.sub,
AtHash: "PRzSZsEPQVqzY8xyB2ls5A",
Nonce: "abc",
Name: user.name_ja,
GivenName: user.given_name,
FamilyName: user.family_name,
Locale: user.locale,
Iat: time.Now().Unix(),
Exp: time.Now().Unix() + ACCESS_TOKEN_DURATION,
}
payload_json, _ := json.Marshal(payload)
//base64エンコード
b64header := base64.RawURLEncoding.EncodeToString(header)
b64payload := base64.RawURLEncoding.EncodeToString(payload_json)
return fmt.Sprintf("%s.%s", b64header, b64payload)
}
// JWTを作成
func makeJWT() (string, error) {
jwtString := makeHeaderPayload()
privateKey, err := readPrivateKey()
if err != nil {
return "", err
}
err = privateKey.Validate()
if err != nil {
return "", fmt.Errorf("private key validate err : %s", err)
}
hasher := sha256.New()
hasher.Write([]byte(jwtString))
tokenHash := hasher.Sum(nil)
// 署名を作成
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, tokenHash)
if err != nil {
return "", fmt.Errorf("sign by private key is err : %s", err)
}
enc := base64.RawURLEncoding.EncodeToString(signature)
// "ヘッダー.ペイロード.署名"を作成して返す
return fmt.Sprintf("%s.%s", jwtString, enc), nil
}
// JWKを作成してJSONにして返す
func makeJWK() []byte {
data, _ := ioutil.ReadFile("public-key.pem")
keyset, _ := jwk.ParseKey(data, jwk.WithPEM(true))
keyset.Set(jwk.KeyIDKey, "12345678")
keyset.Set(jwk.AlgorithmKey, "RS256")
keyset.Set(jwk.KeyUsageKey, "sig")
jwk := map[string]interface{}{
"keys": []interface{}{keyset},
}
buf, _ := json.MarshalIndent(jwk, "", " ")
return buf
}