github.com/Axway/agent-sdk@v1.1.101/pkg/util/encrypt.go (about)

     1  package util
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/rsa"
     6  	"crypto/sha256"
     7  	"crypto/x509"
     8  	"encoding/pem"
     9  	"fmt"
    10  	"hash"
    11  )
    12  
    13  // Encryptor is an interface for encrypting strings
    14  type Encryptor interface {
    15  	Encrypt(str string) (string, error)
    16  }
    17  
    18  // Decryptor is an interface for Decrypting strings
    19  type Decryptor interface {
    20  	Decrypt(str string) (string, error)
    21  }
    22  
    23  // encryptor implements the Encryptor interface
    24  type encryptor struct {
    25  	alg  string
    26  	key  *rsa.PublicKey
    27  	hash hash.Hash
    28  }
    29  
    30  // NewEncryptor creates a struct to handle encryption based on the provided key, algorithm, and hash.
    31  func NewEncryptor(key, alg, hash string) (Encryptor, error) {
    32  	enc := &encryptor{
    33  		alg: alg,
    34  	}
    35  
    36  	pub, err := enc.newPub(key)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	h, err := enc.newHash(hash)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	ok := enc.validateAlg()
    47  	if !ok {
    48  		return nil, fmt.Errorf("unexpected encryption algorithm: %s", alg)
    49  	}
    50  
    51  	enc.hash = h
    52  	enc.key = pub
    53  	return enc, nil
    54  }
    55  
    56  // Encrypt encrypts a string based on the provided public key and algorithm.
    57  func (e *encryptor) Encrypt(str string) (string, error) {
    58  	bts, err := e.encAlgorithm(str)
    59  	if err != nil {
    60  		return "", fmt.Errorf("failed to encrypt: %s", err)
    61  	}
    62  
    63  	return string(bts), nil
    64  }
    65  
    66  func (e *encryptor) newPub(key string) (*rsa.PublicKey, error) {
    67  	block, _ := pem.Decode([]byte(key))
    68  	if block == nil {
    69  		return nil, fmt.Errorf("failed to decode public key")
    70  	}
    71  	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
    72  	if err != nil {
    73  		return nil, fmt.Errorf("failed to parse public key: %s", err)
    74  	}
    75  
    76  	p, ok := pub.(*rsa.PublicKey)
    77  	if !ok {
    78  		return nil, fmt.Errorf("expected public key type to be *rsa.PublicKey but received %T", pub)
    79  	}
    80  
    81  	return p, nil
    82  }
    83  
    84  func (e *encryptor) newHash(hash string) (hash.Hash, error) {
    85  	switch hash {
    86  	case "":
    87  		fallthrough
    88  	case "SHA256":
    89  		return sha256.New(), nil
    90  	default:
    91  		return nil, fmt.Errorf("unexpected encryption hash: %s", hash)
    92  	}
    93  }
    94  
    95  func (e *encryptor) validateAlg() bool {
    96  	switch e.alg {
    97  	case "":
    98  		fallthrough
    99  	case "RSA-OAEP":
   100  		return true
   101  	case "PKCS":
   102  		return true
   103  	default:
   104  		return false
   105  	}
   106  }
   107  
   108  func (e *encryptor) encAlgorithm(msg string) ([]byte, error) {
   109  	switch e.alg {
   110  	case "":
   111  		fallthrough
   112  	case "RSA-OAEP":
   113  		return rsa.EncryptOAEP(e.hash, rand.Reader, e.key, []byte(msg), nil)
   114  	case "PKCS":
   115  		return rsa.EncryptPKCS1v15(rand.Reader, e.key, []byte(msg))
   116  	default:
   117  		return nil, fmt.Errorf("unexpected encryption algorithm: %s", e.alg)
   118  	}
   119  }