Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for HMAC-SHA256 signatures #40

Merged
merged 1 commit into from
Jul 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions auther_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ func TestSigner_Default(t *testing.T) {
assert.Equal(t, expectedSignature, digest)
}

func TestSigner_SHA256(t *testing.T) {
config := &Config{
Signer: &HMAC256Signer{ConsumerSecret: "consumer_secret"},
}
a := newAuther(config)
// echo -n "hello world" | openssl dgst -sha256 -hmac "consumer_secret&token_secret" -binary | base64
expectedSignature := "pW9drXUyErU8DASWbsP2I3XZbju37AW+VzcGdYSeMo8="
// assert that the signer produces the expected HMAC-SHA256 digest
method := a.signer().Name()
digest, err := a.signer().Sign("token_secret", "hello world")
assert.Nil(t, err)
assert.Equal(t, "HMAC-SHA256", method)
assert.Equal(t, expectedSignature, digest)
}

type identitySigner struct{}

func (s *identitySigner) Name() string {
Expand Down
33 changes: 28 additions & 5 deletions signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
"hash"
"strings"
)

Expand All @@ -29,16 +31,37 @@ func (s *HMACSigner) Name() string {
return "HMAC-SHA1"
}

// Sign creates a concatenated consumer and token secret key and calculates
// the HMAC digest of the message. Returns the base64 encoded digest bytes.
func (s *HMACSigner) Sign(tokenSecret, message string) (string, error) {
signingKey := strings.Join([]string{s.ConsumerSecret, tokenSecret}, "&")
mac := hmac.New(sha1.New, []byte(signingKey))
func hmacSign(consumerSecret, tokenSecret, message string, algo func() hash.Hash) (string, error) {
signingKey := strings.Join([]string{consumerSecret, tokenSecret}, "&")
mac := hmac.New(algo, []byte(signingKey))
mac.Write([]byte(message))
signatureBytes := mac.Sum(nil)
return base64.StdEncoding.EncodeToString(signatureBytes), nil
}

// Sign creates a concatenated consumer and token secret key and calculates
// the HMAC digest of the message. Returns the base64 encoded digest bytes.
func (s *HMACSigner) Sign(tokenSecret, message string) (string, error) {
return hmacSign(s.ConsumerSecret, tokenSecret, message, sha1.New)
}

// HMAC256Signer signs messages with an HMAC SHA256 digest, using the concatenated
// consumer secret and token secret as the key.
type HMAC256Signer struct {
ConsumerSecret string
}

// Name returns the HMAC-SHA256 method.
func (s *HMAC256Signer) Name() string {
return "HMAC-SHA256"
}

// Sign creates a concatenated consumer and token secret key and calculates
// the HMAC digest of the message. Returns the base64 encoded digest bytes.
func (s *HMAC256Signer) Sign(tokenSecret, message string) (string, error) {
return hmacSign(s.ConsumerSecret, tokenSecret, message, sha256.New)
}

// RSASigner RSA PKCS1-v1_5 signs SHA1 digests of messages using the given
// RSA private key.
type RSASigner struct {
Expand Down