Skip to content
This repository has been archived by the owner on May 21, 2022. It is now read-only.

key is invalid #256

Closed
ezechidc opened this issue Apr 5, 2018 · 5 comments
Closed

key is invalid #256

ezechidc opened this issue Apr 5, 2018 · 5 comments

Comments

@ezechidc
Copy link

ezechidc commented Apr 5, 2018

I generated private and public keys using

openssl genrsa -out keys/app.rsa 2048 && openssl rsa -in keys/app.rsa -outform PEM -pubout -out keys/app.rsa.pub

Then when I tried to generate jwt token with code below I get key invalid.

type AppClaims struct {
	UserName string `json:"username"`
	Role     string `json:"role"`
	jwt.StandardClaims
}

const (
	// openssl genrsa -out app.rsa 1024
	privKeyPath = "keys/app.rsa"
	// openssl rsa -in app.rsa -pubout > app.rsa.pub
	pubKeyPath = "keys/app.rsa.pub"
)

var (
	verifyKey, signKey []byte
)

func initKeys() {
	var err error
	signKey, err = ioutil.ReadFile(privKeyPath)
	if err != nil {
		log.Fatalf("[initKeys]: %s\n", err)
	}
	verifyKey, err = ioutil.ReadFile(pubKeyPath)
	if err != nil {
		log.Fatalf("[initKeys]: %s\n", err)
		panic(err)
	}
}

// Generate JWT token
func GenerateJWT(name, role string) (string, error) {
	// Create the Claims
	claims := AppClaims{
		name,
		role,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Minute * 20).Unix(),
			Issuer:    "admin",
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
	ss, err := token.SignedString(signKey)
	log.Print(token)
	if err != nil {
		return "", err
	}
	return ss, nil
}

As you can see from the above signKey is of type []byte I don't know what is wrong with the code above please help me figure out what is wrong just learning go.

@umpc
Copy link

umpc commented Apr 5, 2018

Hopefully the author can chime in with a more detailed answer, though I had to use Go to generate my keys. I will edit this later today and post the code that I used if I can find it, unless the issue is solved.

Edit: The code that I used was from here:
https://github.com/swytman/geokewpie/blob/master/gen_cert.go

You may want to modify the template.Subject.Organization value to your organization or name.

@dgrijalva
Copy link
Owner

The RSA signing methods require a *rsa.PrivateKey as the key. Each signing method requires a different type for the key. This is the most common point of confusion with users of this library, but it's important for a few reasons:

  • The underlying signing code (from the standard library) have different key type requirements
  • These keys are composed of a different number of values
  • There are many different methods of serialization for each
  • Finally, and unrelated to the previous, this dramatically reduces the impact of the most well known attack on JWT tokens. This is more applicable to parsing than signing, but for the sake of symmetry...

See the required key types in the README or the documentation.

@dgrijalva
Copy link
Owner

Also, I believe the (in progress) 4.0 version of the library will update the error to more accurately state whether the key is invalid or the key type.

@ezechidc
Copy link
Author

ezechidc commented Apr 7, 2018

@dgrijalva Thanks for your help this (*rsa.PrivateKey) was the missing link error message wasn't clear enough. I used https://gist.github.com/sdorra/1c95de8cb80da31610d2ad767cd6f251 to generate private and public keys and then modified this bit from the code above.

var (
	verifyKey *rsa.PublicKey
	signKey   *rsa.PrivateKey
)

// Read the key files before starting http handlers
func initKeys() {
	var err error
	signKeyByte, err := ioutil.ReadFile(privKeyPath)
	signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signKeyByte)
	if err != nil {
		log.Fatalf("[initKeys]: %s\n", err)
	}
	verifyKeyByte, err := ioutil.ReadFile(pubKeyPath)
	verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyKeyByte)
	if err != nil {
		log.Fatalf("[initKeys]: %s\n", err)
		panic(err)
	}
}

@ezechidc ezechidc closed this as completed Apr 8, 2018
@larytet
Copy link

larytet commented Nov 9, 2020

Just in case you need an example, this code works:

	package main

	import (
		"testing"
		"time"

		"crypto/rand"
		"crypto/rsa"
		jwtgo "github.com/dgrijalva/jwt-go"
	)


	func Test_jwtSignRS(t *testing.T) {
		privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
		if err != nil {
			t.Fatalf("Failed to generate a pair of keys %v", err)
		}
		
		now := time.Now()
		
		type TestClaims struct {
			HAPP string  `json:"happ"`
			jwtgo.StandardClaims
		}
		
		// Create the Claims
		testClaims := TestClaims{
			"owa",
			jwtgo.StandardClaims{
				ExpiresAt: now.Add(time.Minute).Unix(),
				NotBefore: now.Unix(),
				Issuer:    "test",
			},
		}	
		
		// https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA
		token := jwtgo.NewWithClaims(jwtgo.SigningMethodRS256, testClaims)
		
		// See https://godoc.org/github.com/dgrijalva/jwt-go#Token.SigningString
		signedString, errSignedString := token.SignedString(privateKey)
		if errSignedString != nil {
			t.Fatalf("Failed to sign %v", errSignedString)
		}
		t.Logf("Signed token=%v", signedString)	
	}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants