9
9
"crypto/elliptic"
10
10
"crypto/rand"
11
11
"crypto/rsa"
12
+ "crypto/sha256"
12
13
"crypto/x509"
13
14
"encoding/base64"
14
15
"encoding/pem"
@@ -43,7 +44,7 @@ type JWTSigningKey interface {
43
44
SigningMethod () jwt.SigningMethod
44
45
SignKey () interface {}
45
46
VerifyKey () interface {}
46
- ToJSON () map [string ]string
47
+ ToJWK () ( map [string ]string , error )
47
48
}
48
49
49
50
type hmacSingingKey struct {
@@ -67,8 +68,8 @@ func (key hmacSingingKey) VerifyKey() interface{} {
67
68
return key .secret
68
69
}
69
70
70
- func (key hmacSingingKey ) ToJSON () map [string ]string {
71
- return map [string ]string {}
71
+ func (key hmacSingingKey ) ToJWK () ( map [string ]string , error ) {
72
+ return map [string ]string {}, nil
72
73
}
73
74
74
75
type rsaSingingKey struct {
@@ -92,15 +93,21 @@ func (key rsaSingingKey) VerifyKey() interface{} {
92
93
return key .key .Public ()
93
94
}
94
95
95
- func (key rsaSingingKey ) ToJSON () map [string ]string {
96
+ func (key rsaSingingKey ) ToJWK () ( map [string ]string , error ) {
96
97
pubKey := key .key .Public ().(* rsa.PublicKey )
97
98
99
+ kid , err := createPublicKeyFingerprint (pubKey )
100
+ if err != nil {
101
+ return nil , err
102
+ }
103
+
98
104
return map [string ]string {
99
105
"kty" : "RSA" ,
100
106
"alg" : key .SigningMethod ().Alg (),
107
+ "kid" : base64 .RawURLEncoding .EncodeToString (kid ),
101
108
"e" : base64 .RawURLEncoding .EncodeToString (big .NewInt (int64 (pubKey .E )).Bytes ()),
102
109
"n" : base64 .RawURLEncoding .EncodeToString (pubKey .N .Bytes ()),
103
- }
110
+ }, nil
104
111
}
105
112
106
113
type ecdsaSingingKey struct {
@@ -124,16 +131,33 @@ func (key ecdsaSingingKey) VerifyKey() interface{} {
124
131
return key .key .Public ()
125
132
}
126
133
127
- func (key ecdsaSingingKey ) ToJSON () map [string ]string {
134
+ func (key ecdsaSingingKey ) ToJWK () ( map [string ]string , error ) {
128
135
pubKey := key .key .Public ().(* ecdsa.PublicKey )
129
136
137
+ kid , err := createPublicKeyFingerprint (pubKey )
138
+ if err != nil {
139
+ return nil , err
140
+ }
141
+
130
142
return map [string ]string {
131
143
"kty" : "EC" ,
132
144
"alg" : key .SigningMethod ().Alg (),
145
+ "kid" : base64 .RawURLEncoding .EncodeToString (kid ),
133
146
"crv" : pubKey .Params ().Name ,
134
147
"x" : base64 .RawURLEncoding .EncodeToString (pubKey .X .Bytes ()),
135
148
"y" : base64 .RawURLEncoding .EncodeToString (pubKey .Y .Bytes ()),
149
+ }, nil
150
+ }
151
+
152
+ func createPublicKeyFingerprint (key interface {}) ([]byte , error ) {
153
+ bytes , err := x509 .MarshalPKIXPublicKey (key )
154
+ if err != nil {
155
+ return nil , err
136
156
}
157
+
158
+ checksum := sha256 .Sum256 (bytes )
159
+
160
+ return checksum [:], nil
137
161
}
138
162
139
163
// CreateJWTSingingKey creates a signing key from an algorithm / key pair.
0 commit comments