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 }