...

Source file src/github.com/golang-jwt/jwt/hmac.go

Documentation: github.com/golang-jwt/jwt

     1  package jwt
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/hmac"
     6  	"errors"
     7  )
     8  
     9  // Implements the HMAC-SHA family of signing methods signing methods
    10  // Expects key type of []byte for both signing and validation
    11  type SigningMethodHMAC struct {
    12  	Name string
    13  	Hash crypto.Hash
    14  }
    15  
    16  // Specific instances for HS256 and company
    17  var (
    18  	SigningMethodHS256  *SigningMethodHMAC
    19  	SigningMethodHS384  *SigningMethodHMAC
    20  	SigningMethodHS512  *SigningMethodHMAC
    21  	ErrSignatureInvalid = errors.New("signature is invalid")
    22  )
    23  
    24  func init() {
    25  	// HS256
    26  	SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256}
    27  	RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod {
    28  		return SigningMethodHS256
    29  	})
    30  
    31  	// HS384
    32  	SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384}
    33  	RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod {
    34  		return SigningMethodHS384
    35  	})
    36  
    37  	// HS512
    38  	SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512}
    39  	RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod {
    40  		return SigningMethodHS512
    41  	})
    42  }
    43  
    44  func (m *SigningMethodHMAC) Alg() string {
    45  	return m.Name
    46  }
    47  
    48  // Verify the signature of HSXXX tokens.  Returns nil if the signature is valid.
    49  func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error {
    50  	// Verify the key is the right type
    51  	keyBytes, ok := key.([]byte)
    52  	if !ok {
    53  		return ErrInvalidKeyType
    54  	}
    55  
    56  	// Decode signature, for comparison
    57  	sig, err := DecodeSegment(signature)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	// Can we use the specified hashing method?
    63  	if !m.Hash.Available() {
    64  		return ErrHashUnavailable
    65  	}
    66  
    67  	// This signing method is symmetric, so we validate the signature
    68  	// by reproducing the signature from the signing string and key, then
    69  	// comparing that against the provided signature.
    70  	hasher := hmac.New(m.Hash.New, keyBytes)
    71  	hasher.Write([]byte(signingString))
    72  	if !hmac.Equal(sig, hasher.Sum(nil)) {
    73  		return ErrSignatureInvalid
    74  	}
    75  
    76  	// No validation errors.  Signature is good.
    77  	return nil
    78  }
    79  
    80  // Implements the Sign method from SigningMethod for this signing method.
    81  // Key must be []byte
    82  func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
    83  	if keyBytes, ok := key.([]byte); ok {
    84  		if !m.Hash.Available() {
    85  			return "", ErrHashUnavailable
    86  		}
    87  
    88  		hasher := hmac.New(m.Hash.New, keyBytes)
    89  		hasher.Write([]byte(signingString))
    90  
    91  		return EncodeSegment(hasher.Sum(nil)), nil
    92  	}
    93  
    94  	return "", ErrInvalidKeyType
    95  }
    96  

View as plain text