...

Source file src/edge-infra.dev/pkg/edge/edgeencrypt/encrypt.go

Documentation: edge-infra.dev/pkg/edge/edgeencrypt

     1  package edgeencrypt
     2  
     3  import (
     4  	"crypto/aes"
     5  	"crypto/cipher"
     6  	"crypto/rand"
     7  	"crypto/rsa"
     8  	"crypto/sha256"
     9  	"crypto/x509"
    10  	"encoding/pem"
    11  	"fmt"
    12  	"io"
    13  )
    14  
    15  const (
    16  	KeySize = 256
    17  )
    18  
    19  // EncryptData encrypts data using RSA public key, using 256 bit AES key
    20  func EncryptData(pemPublicKey string, data []byte) ([]byte, error) {
    21  	rsaPublicKey, err := toRSAPublicKey(pemPublicKey)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	aesKey, err := geneRandomAES256BitKey()
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  
    30  	cryptoData, err := encryptData(data, aesKey)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	cryptoKey, err := encryptEASKey(rsaPublicKey, aesKey)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  
    39  	encryptedData := append(cryptoKey, cryptoData...)
    40  	return encryptedData, nil
    41  }
    42  
    43  func toRSAPublicKey(pemPublicKey string) (*rsa.PublicKey, error) {
    44  	block, _ := pem.Decode([]byte(pemPublicKey))
    45  	pk, err := x509.ParsePKIXPublicKey(block.Bytes)
    46  	if err != nil {
    47  		return nil, fmt.Errorf("failed to parse public key: %w", err)
    48  	}
    49  	rsaKey, ok := pk.(*rsa.PublicKey)
    50  	if !ok {
    51  		return nil, fmt.Errorf("public key is not in rsa format")
    52  	}
    53  	return rsaKey, nil
    54  }
    55  
    56  func geneRandomAES256BitKey() ([]byte, error) {
    57  	key := make([]byte, 32) // AES-256
    58  	if _, err := rand.Read(key); err != nil {
    59  		return nil, fmt.Errorf("failed to generate random key: %w", err)
    60  	}
    61  	return key, nil
    62  }
    63  
    64  func encryptData(data, aesKey []byte) ([]byte, error) {
    65  	blockCipher, err := aes.NewCipher(aesKey)
    66  	if err != nil {
    67  		return nil, fmt.Errorf("failed to create AES cipher: %w", err)
    68  	}
    69  	gcm, err := cipher.NewGCM(blockCipher)
    70  	if err != nil {
    71  		return nil, fmt.Errorf("failed to create GCM: %w", err)
    72  	}
    73  	nonce := make([]byte, gcm.NonceSize())
    74  	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
    75  		return nil, fmt.Errorf("failed to generate nonce: %w", err)
    76  	}
    77  	return gcm.Seal(nonce, nonce, data, nil), nil
    78  }
    79  
    80  func encryptEASKey(rsaKey *rsa.PublicKey, aesKey []byte) ([]byte, error) {
    81  	return rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaKey, aesKey, nil)
    82  }
    83  

View as plain text