概要
lestrrat-goでJWSの署名作成と検証をやってみた。
コード
package main
import (
"crypto/rand"
"crypto/rsa"
"encoding/json"
"time"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/lestrrat-go/jwx/v2/jwt"
)
func toJwksJson(kid string, rawKey interface{}) string {
jwkSet := jwk.NewSet()
key, _ := jwk.FromRaw(rawKey)
key.Set(jwk.KeyIDKey, kid)
jwkSet.AddKey(key)
jb, _ := json.Marshal(jwkSet)
return string(jb)
}
func main() {
// RS256
privateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
publicKey := &(privateKey.PublicKey)
signOption := jwt.WithKey(jwa.RS256, privateKey)
parseOption := jwt.WithKey(jwa.RS256, publicKey)
tok, err := jwt.NewBuilder().
Claim("username", "bobunderson").
Claim("foo", "bar").
Issuer("myauth.example.com").
IssuedAt(time.Now()).
Audience([]string{"myapp.example.com"}).
Build()
if err != nil {
panic(err)
}
print("===== jwks =====\n")
jwksJson := toJwksJson("test-key", publicKey)
print(jwksJson, "\n\n")
print("===== private key =====\n")
jwkPrivate, _ := jwk.FromRaw(privateKey)
privateKeyJsonBytes, _ := json.Marshal(jwkPrivate)
privateKeyJson := string(privateKeyJsonBytes)
print(privateKeyJson, "\n\n")
print("===== public key =====\n")
jwkPublic, _ := jwk.FromRaw(publicKey)
publicKeyJsonBytes, _ := json.Marshal(jwkPublic)
publicKeyJson := string(publicKeyJsonBytes)
print(publicKeyJson, "\n\n")
print("===== jws =====\n")
bytesJWS, err := jwt.Sign(tok, signOption)
if err != nil {
panic(err)
}
print(string(bytesJWS), "\n\n")
print("===== validation result =====\n")
_, err = jwt.Parse(bytesJWS, parseOption, jwt.WithValidate(true))
if err != nil {
panic(err)
}
print("ok\n")
}
他の署名アルゴリズムに対応
-
HS256
... // HS256 privateKey := []byte("my-secret-key") publicKey := privateKey signOption := jwt.WithKey(jwa.HS256, privateKey) parseOption := jwt.WithKey(jwa.HS256, publicKey) ...
-
ES256
... // ES256 privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) publicKey := &(privateKey.PublicKey) signOption := jwt.WithKey(jwa.ES256, privateKey) parseOption := jwt.WithKey(jwa.ES256, publicKey) ...
-
crypto/ecdsa
とcrypto/elliptic
のimportが必要
-