From c48998190f159af398a1bb80d1007e5e393b06f2 Mon Sep 17 00:00:00 2001 From: Klaus Brunner Date: Tue, 26 May 2020 12:33:37 +0200 Subject: [PATCH] Add support for HMAC-SHA256 signatures --- auther_test.go | 15 +++++++++++++++ signer.go | 33 ++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/auther_test.go b/auther_test.go index 2e4cd04..6eb2ce8 100644 --- a/auther_test.go +++ b/auther_test.go @@ -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 { diff --git a/signer.go b/signer.go index 341c859..2f8ac5e 100644 --- a/signer.go +++ b/signer.go @@ -6,7 +6,9 @@ import ( "crypto/rand" "crypto/rsa" "crypto/sha1" + "crypto/sha256" "encoding/base64" + "hash" "strings" ) @@ -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 {