From caa4cf4c8dbdde54c5a0db292e3b89b9cd64b8ad Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 3 Sep 2024 14:23:52 +0200 Subject: [PATCH] Switch to asymetric keys for jwt signing --- auth/config.go | 41 ++++++++++++++++++++++++++++------------- auth/session.go | 6 +++--- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/auth/config.go b/auth/config.go index aa777216..1a509030 100644 --- a/auth/config.go +++ b/auth/config.go @@ -3,7 +3,9 @@ package main import ( "context" "crypto/rand" - "encoding/base64" + "crypto/rsa" + "crypto/x509" + "encoding/pem" "time" "github.com/golang-jwt/jwt/v5" @@ -11,14 +13,15 @@ import ( ) type Configuration struct { - JwtSecret []byte - Issuer string - DefaultClaims jwt.MapClaims + JwtPrivateKey *rsa.PrivateKey + JwtPublicKey *rsa.PublicKey + Issuer string + DefaultClaims jwt.MapClaims ExpirationDelay time.Duration } const ( - JwtSecret = "jwt_secret" + JwtPrivateKey = "jwt_private_key" ) func LoadConfiguration(db *dbc.Queries) (*Configuration, error) { @@ -32,22 +35,34 @@ func LoadConfiguration(db *dbc.Queries) (*Configuration, error) { for _, conf := range confs { switch conf.Key { - case JwtSecret: - secret, err := base64.StdEncoding.DecodeString(conf.Value) + case JwtPrivateKey: + block, _ := pem.Decode([]byte(conf.Value)) + key, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, err } - ret.JwtSecret = secret + ret.JwtPrivateKey = key + ret.JwtPublicKey = &key.PublicKey } } - if ret.JwtSecret == nil { - ret.JwtSecret = make([]byte, 128) - rand.Read(ret.JwtSecret) + if ret.JwtPrivateKey == nil { + ret.JwtPrivateKey, err = rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + return nil, err + } + ret.JwtPublicKey = &ret.JwtPrivateKey.PublicKey + + pemd := pem.EncodeToMemory( + &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(ret.JwtPrivateKey), + }, + ) _, err := db.SaveConfig(ctx, dbc.SaveConfigParams{ - Key: JwtSecret, - Value: base64.StdEncoding.EncodeToString(ret.JwtSecret), + Key: JwtPrivateKey, + Value: string(pemd), }) if err != nil { return nil, err diff --git a/auth/session.go b/auth/session.go index 6e9a265f..3a91ee86 100644 --- a/auth/session.go +++ b/auth/session.go @@ -100,7 +100,6 @@ type Jwt struct { // @Summary Get JWT // @Description Convert a session token to a short lived JWT. // @Tags sessions -// @Accept json // @Produce json // @Security Token // @Success 200 {object} Jwt @@ -129,6 +128,7 @@ func (h *Handler) CreateJwt(c echo.Context) error { claims := maps.Clone(session.User.Claims) claims["sub"] = session.User.Id.String() + claims["sid"] = session.Id.String() claims["iss"] = h.config.Issuer claims["exp"] = &jwt.NumericDate{ Time: time.Now().UTC().Add(time.Hour), @@ -136,8 +136,8 @@ func (h *Handler) CreateJwt(c echo.Context) error { claims["iss"] = &jwt.NumericDate{ Time: time.Now().UTC(), } - jwt := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - t, err := jwt.SignedString(h.config.JwtSecret) + jwt := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) + t, err := jwt.SignedString(h.config.JwtPrivateKey) if err != nil { return err }