Skip to content

Instantly share code, notes, and snippets.

@uzimith
Created April 19, 2017 06:11
Show Gist options
  • Save uzimith/524827b12f1fa194364d4de094d63793 to your computer and use it in GitHub Desktop.
Save uzimith/524827b12f1fa194364d4de094d63793 to your computer and use it in GitHub Desktop.
// JWKから公開鍵を作る
type JWK struct {
Keys []struct {
Kty string `json:"kty"`
Alg string `json:"alg"`
Use string `json:"use"`
Kid string `json:"kid"`
N string `json:"n"`
E string `json:"e"`
} `json:"keys"`
}
func createKeyV3(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
var jwk JWK
res, _ := http.Get("https://www.googleapis.com/oauth2/v3/certs")
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
err := json.Unmarshal(body, &jwk)
if err != nil {
return nil, err
}
if kid, ok := token.Header["kid"].(string); ok {
for _, key := range jwk.Keys {
if key.Kid == kid {
return CreateRSAPublicKeyFromJWK(key.N, key.E)
}
}
}
return nil, fmt.Errorf("no RSA PublicKey")
}
func CreateRSAPublicKeyFromJWK(strN string, strE string) (*rsa.PublicKey, error) {
modulus, err := decodeModulus(strN)
if err != nil {
return nil, err
}
exponent, err := decodeExponent(strN)
if err != nil {
return nil, err
}
pKey := rsa.PublicKey{N: modulus, E: exponent}
return &pKey, nil
}
func decodeExponent(e string) (int, error) {
decE, err := decodeBase64URLPaddingOptional(e)
if err != nil {
return 0, err
}
var eBytes []byte
if len(decE) < 8 {
eBytes = make([]byte, 8-len(decE), 8)
eBytes = append(eBytes, decE...)
} else {
eBytes = decE
}
eReader := bytes.NewReader(eBytes)
var E uint64
err = binary.Read(eReader, binary.BigEndian, &E)
if err != nil {
return 0, err
}
return int(E), nil
}
func decodeModulus(n string) (*big.Int, error) {
decN, err := decodeBase64URLPaddingOptional(n)
if err != nil {
return nil, err
}
N := big.NewInt(0)
N.SetBytes(decN)
return N, nil
}
func decodeBase64URLPaddingOptional(e string) ([]byte, error) {
if m := len(e) % 4; m != 0 {
e += strings.Repeat("=", 4-m)
}
return base64.URLEncoding.DecodeString(e)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment