...

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

Documentation: github.com/golang-jwt/jwt/v5

     1  package jwt
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/hmac"
     6  	"errors"
     7  )
     8  
     9  // SigningMethodHMAC implements the HMAC-SHA family of 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 implements token verification for the SigningMethod. Returns nil if
    49  // the signature is valid. Key must be []byte.
    50  //
    51  // Note it is not advised to provide a []byte which was converted from a 'human
    52  // readable' string using a subset of ASCII characters. To maximize entropy, you
    53  // should ideally be providing a []byte key which was produced from a
    54  // cryptographically random source, e.g. crypto/rand. Additional information
    55  // about this, and why we intentionally are not supporting string as a key can
    56  // be found on our usage guide
    57  // https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types.
    58  func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interface{}) error {
    59  	// Verify the key is the right type
    60  	keyBytes, ok := key.([]byte)
    61  	if !ok {
    62  		return newError("HMAC verify expects []byte", ErrInvalidKeyType)
    63  	}
    64  
    65  	// Can we use the specified hashing method?
    66  	if !m.Hash.Available() {
    67  		return ErrHashUnavailable
    68  	}
    69  
    70  	// This signing method is symmetric, so we validate the signature
    71  	// by reproducing the signature from the signing string and key, then
    72  	// comparing that against the provided signature.
    73  	hasher := hmac.New(m.Hash.New, keyBytes)
    74  	hasher.Write([]byte(signingString))
    75  	if !hmac.Equal(sig, hasher.Sum(nil)) {
    76  		return ErrSignatureInvalid
    77  	}
    78  
    79  	// No validation errors.  Signature is good.
    80  	return nil
    81  }
    82  
    83  // Sign implements token signing for the SigningMethod. Key must be []byte.
    84  //
    85  // Note it is not advised to provide a []byte which was converted from a 'human
    86  // readable' string using a subset of ASCII characters. To maximize entropy, you
    87  // should ideally be providing a []byte key which was produced from a
    88  // cryptographically random source, e.g. crypto/rand. Additional information
    89  // about this, and why we intentionally are not supporting string as a key can
    90  // be found on our usage guide https://golang-jwt.github.io/jwt/usage/signing_methods/.
    91  func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) {
    92  	if keyBytes, ok := key.([]byte); ok {
    93  		if !m.Hash.Available() {
    94  			return nil, ErrHashUnavailable
    95  		}
    96  
    97  		hasher := hmac.New(m.Hash.New, keyBytes)
    98  		hasher.Write([]byte(signingString))
    99  
   100  		return hasher.Sum(nil), nil
   101  	}
   102  
   103  	return nil, newError("HMAC sign expects []byte", ErrInvalidKeyType)
   104  }
   105  

View as plain text