rsa.go (2440B)
1 package jwt 2 3 import ( 4 "crypto" 5 "crypto/rand" 6 "crypto/rsa" 7 ) 8 9 // Implements the RSA family of signing methods signing methods 10 // Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation 11 type SigningMethodRSA struct { 12 Name string 13 Hash crypto.Hash 14 } 15 16 // Specific instances for RS256 and company 17 var ( 18 SigningMethodRS256 *SigningMethodRSA 19 SigningMethodRS384 *SigningMethodRSA 20 SigningMethodRS512 *SigningMethodRSA 21 ) 22 23 func init() { 24 // RS256 25 SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} 26 RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { 27 return SigningMethodRS256 28 }) 29 30 // RS384 31 SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} 32 RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { 33 return SigningMethodRS384 34 }) 35 36 // RS512 37 SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} 38 RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { 39 return SigningMethodRS512 40 }) 41 } 42 43 func (m *SigningMethodRSA) Alg() string { 44 return m.Name 45 } 46 47 // Implements the Verify method from SigningMethod 48 // For this signing method, must be an *rsa.PublicKey structure. 49 func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { 50 var err error 51 52 // Decode the signature 53 var sig []byte 54 if sig, err = DecodeSegment(signature); err != nil { 55 return err 56 } 57 58 var rsaKey *rsa.PublicKey 59 var ok bool 60 61 if rsaKey, ok = key.(*rsa.PublicKey); !ok { 62 return ErrInvalidKeyType 63 } 64 65 // Create hasher 66 if !m.Hash.Available() { 67 return ErrHashUnavailable 68 } 69 hasher := m.Hash.New() 70 hasher.Write([]byte(signingString)) 71 72 // Verify the signature 73 return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) 74 } 75 76 // Implements the Sign method from SigningMethod 77 // For this signing method, must be an *rsa.PrivateKey structure. 78 func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { 79 var rsaKey *rsa.PrivateKey 80 var ok bool 81 82 // Validate type of key 83 if rsaKey, ok = key.(*rsa.PrivateKey); !ok { 84 return "", ErrInvalidKey 85 } 86 87 // Create the hasher 88 if !m.Hash.Available() { 89 return "", ErrHashUnavailable 90 } 91 92 hasher := m.Hash.New() 93 hasher.Write([]byte(signingString)) 94 95 // Sign the string and return the encoded bytes 96 if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { 97 return EncodeSegment(sigBytes), nil 98 } else { 99 return "", err 100 } 101 }