github.com/fzfile/BaiduPCS-Go@v0.0.0-20200606205115-4408961cf336/pcsutil/jwted25519/jwted25519.go (about)

     1  package jwted25519
     2  
     3  import (
     4  	"github.com/dgrijalva/jwt-go"
     5  	"golang.org/x/crypto/ed25519"
     6  	"unsafe"
     7  )
     8  
     9  type (
    10  	SigningMethodEd25519 struct{}
    11  )
    12  
    13  var (
    14  	SigningMethodED25519 *SigningMethodEd25519
    15  )
    16  
    17  func init() {
    18  	// ED25519
    19  	SigningMethodED25519 = &SigningMethodEd25519{}
    20  	jwt.RegisterSigningMethod(SigningMethodED25519.Alg(), func() jwt.SigningMethod {
    21  		return SigningMethodED25519
    22  	})
    23  }
    24  
    25  func (m *SigningMethodEd25519) Alg() string {
    26  	return "ED25519"
    27  }
    28  
    29  func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) (string, error) {
    30  	if privkey, ok := key.(ed25519.PrivateKey); ok {
    31  		if len(privkey) != ed25519.PrivateKeySize {
    32  			return "", jwt.ErrInvalidKey
    33  		}
    34  
    35  		signature := ed25519.Sign(privkey, *(*[]byte)(unsafe.Pointer(&signingString)))
    36  		return jwt.EncodeSegment(signature), nil
    37  	}
    38  
    39  	return "", jwt.ErrInvalidKeyType
    40  }
    41  
    42  func (m *SigningMethodEd25519) Verify(signingString, signature string, key interface{}) error {
    43  	pubkey, ok := key.(ed25519.PublicKey)
    44  	if !ok {
    45  		return jwt.ErrInvalidKeyType
    46  	}
    47  
    48  	if len(pubkey) != ed25519.PublicKeySize {
    49  		return jwt.ErrInvalidKey
    50  	}
    51  
    52  	message, err := jwt.DecodeSegment(signature)
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	ok = ed25519.Verify(pubkey, *(*[]byte)(unsafe.Pointer(&signingString)), message)
    58  	if !ok {
    59  		return jwt.ErrSignatureInvalid
    60  	}
    61  
    62  	return nil
    63  }