sign.go raw

   1  package authenticator
   2  
   3  import (
   4  	"crypto"
   5  	"crypto/rand"
   6  	"crypto/rsa"
   7  	"crypto/sha512"
   8  	"crypto/x509"
   9  	"encoding/base64"
  10  	"encoding/pem"
  11  	"errors"
  12  	"fmt"
  13  )
  14  
  15  var (
  16  	// ErrDecodingPrivateKey will be thrown when an invalid private key has been given
  17  	ErrDecodingPrivateKey = errors.New("could not decode private key")
  18  )
  19  
  20  func signWithKey(body []byte, key []byte) (string, error) {
  21  	// prepare key struct
  22  	block, _ := pem.Decode(key)
  23  	if block == nil {
  24  		return "", ErrDecodingPrivateKey
  25  	}
  26  	parsed, err := x509.ParsePKCS8PrivateKey(block.Bytes)
  27  	if err != nil {
  28  		return "", fmt.Errorf("could not parse private key: %w", err)
  29  	}
  30  
  31  	pkey, ok := parsed.(*rsa.PrivateKey)
  32  	if !ok {
  33  		return "", fmt.Errorf("private key was no RSA key: %T", parsed)
  34  	}
  35  	digest := sha512.Sum512(body)
  36  
  37  	enc, err := rsa.SignPKCS1v15(rand.Reader, pkey, crypto.SHA512, digest[:])
  38  	if err != nil {
  39  		return "", fmt.Errorf("could not sign data: %w", err)
  40  	}
  41  
  42  	return base64.StdEncoding.EncodeToString(enc), nil
  43  }
  44