I'm using JWKS format to provide from an authentication service the public key that can be used to validate tokens coming from that authentication service. However, to perform validation I need to rebuild the public key from the JWK. How can I convert it?
type JWKeys struct {
Keys []JWKey `json:"keys"`
}
type JWKey struct {
Kty string `json:"kty"`
Use string `json:"use,omitempty"`
Kid string `json:"kid,omitempty"`
Alg string `json:"alg,omitempty"`
Crv string `json:"crv,omitempty"`
X string `json:"x,omitempty"`
Y string `json:"y,omitempty"`
D string `json:"d,omitempty"`
N string `json:"n,omitempty"`
E string `json:"e,omitempty"`
K string `json:"k,omitempty"`
}
var PublicKey *rsa.PublicKey
func SetUpExternalAuth() {
res, err := http.Get("my_url")
if err != nil {
log.Fatal("Can't retrieve the key for authentication")
}
bodyBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
var keys JWKeys
json.Unmarshal(bodyBytes, &keys)
//CONVERT JWK TO *rsa.PUBLICKEY???
}
UPDATE
I tried to parse the JWKs using github.com/lestrrat-go/jwx/jwk library, however I couldn't find how to continue:
set,err := jwk.Parse(bodyBytes)
key,err2 := set.Get(0)
//HOW TO CONVERT KEY INTO A *rsa.PublicKey?
At the end I've manually converted it:
if singleJWK.Kty != "RSA" {
log.Fatal("invalid key type:", singleJWK.Kty)
}
// decode the base64 bytes for n
nb, err := base64.RawURLEncoding.DecodeString(singleJWK.N)
if err != nil {
log.Fatal(err)
}
e := 0
// The default exponent is usually 65537, so just compare the
// base64 for [1,0,1] or [0,1,0,1]
if singleJWK.E == "AQAB" || singleJWK.E == "AAEAAQ" {
e = 65537
} else {
// need to decode "e" as a big-endian int
log.Fatal("need to deocde e:", singleJWK.E)
}
PublicKey = &rsa.PublicKey{
N: new(big.Int).SetBytes(nb),
E: e,
}