jwt-go icon indicating copy to clipboard operation
jwt-go copied to clipboard

jwt key invalid - migrating to new version

Open ORESoftware opened this issue 4 years ago • 1 comments

This used to work with an older version of jwt-go:

if tokenString, err = token.SignedString(config.JwtRSAKey); err != nil {
	return ctr.WriteErrResponse(500, err)
}

where our config.JwtRSAKey looked like:

var (
	JwtRSAKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBALTmXkyFi9So4vNyoGay7EsTIyQDVbW/nU9BQWDcFDlFi4mh6foz
PT6ZbyGEH6EtT6jnQ+POpm7S62kdhAT4CnECAwEAAQJAR93NULEtYArIPtcnCiXC
....
dlhcWMk59B/Z0wIhAI9Dk9mxnzEda8oMgvSAxt1YY/lc3ntoMK2otW3zdScfAiBO
KY0SsHgqeSimJ...a6qS+C8dt+0rfwAE+A==
-----END RSA PRIVATE KEY-----`)
)

but now we get this error:

key is invalid

here is the code in the library that gets the signed string:

 // Get the complete, signed token
func (t *Token) SignedString(key interface{}) (string, error) {
	var sig, sstr string
	var err error
	if sstr, err = t.SigningString(); err != nil {
		return "", err
	}
	if sig, err = t.Method.Sign(sstr, key); err != nil {
		return "", err
	}
	return strings.Join([]string{sstr, sig}, "."), nil
}

is there something wrong about using an RSA key to encrypt? I tried using a plain string instead of bytes and it didn't work either though.

ORESoftware avatar Mar 11 '20 20:03 ORESoftware

I've learned about it the hard way, coming across the problem myself. If you dig down into the code, it turns out you need to pass the parsed *rsa.PrivateKey structure to the token.SignedString function. Here is the relevant function I'm using to turn the encoded token into the desired structure.

var ErrInvalidPrivateKey := errors.New("invalid private key")

func decodePrivateKey(encodedKey string) (*rsa.PrivateKey, error) {
	block, _ := pem.Decode([]byte(encodedKey))
	if block == nil {
		return nil, ErrInvalidPrivateKey
	}

	untypedPrivateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, ErrInvalidPrivateKey
	}

	var privateKey *rsa.PrivateKey
	var ok bool
	if privateKey, ok = untypedPrivateKey.(*rsa.PrivateKey); !ok {
		return nil, ErrInvalidPrivateKey
	}

	return privateKey, nil
}

You might need to use different Parse... function (probably PKCS1 if that's the case). Here: https://golang.org/pkg/crypto/x509 you can find different possibilities.

zemiret avatar Mar 25 '20 11:03 zemiret