Skip to content

Commit

Permalink
Added support for HS384 and HS512 signing methods
Browse files Browse the repository at this point in the history
Renamed type SigningMethodHS256 to SigningMethodHMAC
Added contstants SigningMethodHS256, SigningMethodHS384, and SigningMethodHS512 to support each of these methods
Added simple tests to support these new methods
  • Loading branch information
dgrijalva committed Jul 5, 2014
1 parent fbcb3e4 commit 5aed334
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 56 deletions.
65 changes: 65 additions & 0 deletions hmac.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package jwt

import (
"bytes"
"crypto"
"crypto/hmac"
"errors"
)

type SigningMethodHMAC struct {
Name string
Hash crypto.Hash
}

var (
SigningMethodHS256 *SigningMethodHMAC
SigningMethodHS384 *SigningMethodHMAC
SigningMethodHS512 *SigningMethodHMAC
)

func init() {
// HS256
SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256}
RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod {
return SigningMethodHS256
})

// HS384
SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384}
RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod {
return SigningMethodHS384
})

// HS512
SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512}
RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod {
return SigningMethodHS512
})
}

func (m *SigningMethodHMAC) Alg() string {
return m.Name
}

func (m *SigningMethodHMAC) Verify(signingString, signature string, key []byte) error {
// Key
var sig []byte
var err error
if sig, err = DecodeSegment(signature); err == nil {
hasher := hmac.New(m.Hash.New, key)
hasher.Write([]byte(signingString))

if !bytes.Equal(sig, hasher.Sum(nil)) {
err = errors.New("Signature is invalid")
}
}
return err
}

func (m *SigningMethodHMAC) Sign(signingString string, key []byte) (string, error) {
hasher := hmac.New(m.Hash.New, key)
hasher.Write([]byte(signingString))

return EncodeSegment(hasher.Sum(nil)), nil
}
43 changes: 28 additions & 15 deletions sha256_test.go → hmac_test.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,57 @@
package jwt

import (
"io/ioutil"
"strings"
"testing"
)

var sha256TestData = []struct {
var hmacTestData = []struct {
name string
tokenString string
alg string
claims map[string]interface{}
valid bool
}{
{
"web sample",
"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"HS256",
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
true,
},
{
"HS384",
"eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.KWZEuOD5lbBxZ34g7F-SlVLAQ_r5KApWNWlZIIMyQVz5Zs58a7XdNzj5_0EcNoOy",
"HS384",
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
true,
},
{
"HS512",
"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.CN7YijRX6Aw1n2jyI2Id1w90ja-DEMYiWixhYCyHnrZ1VfJRaFQz1bEbjjA5Fn4CLYaUG432dEYmSbS4Saokmw",
"HS512",
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
true,
},
{
"web sample: invalid",
"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXo",
"HS256",
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
false,
},
}

// Sample data from http://tools.ietf.org/html/draft-jones-json-web-signature-04#appendix-A.1
var sha256TestKey = []byte{
3, 35, 53, 75, 43, 15, 165, 188, 131, 126, 6, 101, 119, 123, 166,
143, 90, 179, 40, 230, 240, 84, 201, 40, 169, 15, 132, 178, 210, 80,
46, 191, 211, 251, 90, 146, 210, 6, 71, 239, 150, 138, 180, 195, 119,
98, 61, 34, 61, 46, 33, 114, 5, 46, 79, 8, 192, 205, 154, 245, 103,
208, 128, 163}
var hmacTestKey, _ = ioutil.ReadFile("test/hmacTestKey")

func TestHS256Verify(t *testing.T) {
for _, data := range sha256TestData {
func TestHMACVerify(t *testing.T) {
for _, data := range hmacTestData {
parts := strings.Split(data.tokenString, ".")

method := GetSigningMethod("HS256")
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], sha256TestKey)
method := GetSigningMethod(data.alg)
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], hmacTestKey)
if data.valid && err != nil {
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
}
Expand All @@ -48,12 +61,12 @@ func TestHS256Verify(t *testing.T) {
}
}

func TestHS256Sign(t *testing.T) {
for _, data := range sha256TestData {
func TestHMACSign(t *testing.T) {
for _, data := range hmacTestData {
if data.valid {
parts := strings.Split(data.tokenString, ".")
method := GetSigningMethod("HS256")
sig, err := method.Sign(strings.Join(parts[0:2], "."), sha256TestKey)
method := GetSigningMethod(data.alg)
sig, err := method.Sign(strings.Join(parts[0:2], "."), hmacTestKey)
if err != nil {
t.Errorf("[%v] Error signing token: %v", data.name, err)
}
Expand Down
41 changes: 0 additions & 41 deletions sha256.go

This file was deleted.

1 change: 1 addition & 0 deletions test/hmacTestKey
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#5K+���~ew{��Z�(��T�(����P.���Z��G��wb="=.!r.O�͚�gЀ�

0 comments on commit 5aed334

Please sign in to comment.