| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 | package backupimport (	"crypto/aes"	"crypto/cipher"	"crypto/rand"	"encoding/base64"	"io"	"os"	"github.com/uozi-tech/cosy")// AESEncrypt encrypts data using AES-256-CBCfunc AESEncrypt(data []byte, key []byte, iv []byte) ([]byte, error) {	block, err := aes.NewCipher(key)	if err != nil {		return nil, cosy.WrapErrorWithParams(ErrEncryptData, err.Error())	}	// Pad data to be a multiple of block size	padding := aes.BlockSize - (len(data) % aes.BlockSize)	padtext := make([]byte, len(data)+padding)	copy(padtext, data)	// PKCS#7 padding	for i := len(data); i < len(padtext); i++ {		padtext[i] = byte(padding)	}	// Create CBC encrypter	mode := cipher.NewCBCEncrypter(block, iv)	encrypted := make([]byte, len(padtext))	mode.CryptBlocks(encrypted, padtext)	return encrypted, nil}// AESDecrypt decrypts data using AES-256-CBCfunc AESDecrypt(encrypted []byte, key []byte, iv []byte) ([]byte, error) {	block, err := aes.NewCipher(key)	if err != nil {		return nil, cosy.WrapErrorWithParams(ErrDecryptData, err.Error())	}	// Create CBC decrypter	mode := cipher.NewCBCDecrypter(block, iv)	decrypted := make([]byte, len(encrypted))	mode.CryptBlocks(decrypted, encrypted)	// Remove padding	padding := int(decrypted[len(decrypted)-1])	if padding < 1 || padding > aes.BlockSize {		return nil, ErrInvalidPadding	}	return decrypted[:len(decrypted)-padding], nil}// GenerateAESKey generates a random 32-byte AES keyfunc GenerateAESKey() ([]byte, error) {	key := make([]byte, 32) // 256-bit key	if _, err := io.ReadFull(rand.Reader, key); err != nil {		return nil, cosy.WrapErrorWithParams(ErrGenerateAESKey, err.Error())	}	return key, nil}// GenerateIV generates a random 16-byte initialization vectorfunc GenerateIV() ([]byte, error) {	iv := make([]byte, aes.BlockSize)	if _, err := io.ReadFull(rand.Reader, iv); err != nil {		return nil, cosy.WrapErrorWithParams(ErrGenerateIV, err.Error())	}	return iv, nil}// encryptFile encrypts a single file using AES encryptionfunc encryptFile(filePath string, key []byte, iv []byte) error {	// Read file content	data, err := os.ReadFile(filePath)	if err != nil {		return cosy.WrapErrorWithParams(ErrReadFile, filePath)	}	// Encrypt file content	encrypted, err := AESEncrypt(data, key, iv)	if err != nil {		return cosy.WrapErrorWithParams(ErrEncryptFile, filePath)	}	// Write encrypted content back	if err := os.WriteFile(filePath, encrypted, 0644); err != nil {		return cosy.WrapErrorWithParams(ErrWriteEncryptedFile, filePath)	}	return nil}// decryptFile decrypts a single file using AES decryptionfunc decryptFile(filePath string, key []byte, iv []byte) error {	// Read encrypted file content	encryptedData, err := os.ReadFile(filePath)	if err != nil {		return cosy.WrapErrorWithParams(ErrReadEncryptedFile, err.Error())	}	// Decrypt file content	decryptedData, err := AESDecrypt(encryptedData, key, iv)	if err != nil {		return cosy.WrapErrorWithParams(ErrDecryptFile, err.Error())	}	// Write decrypted content back	if err := os.WriteFile(filePath, decryptedData, 0644); err != nil {		return cosy.WrapErrorWithParams(ErrWriteDecryptedFile, err.Error())	}	return nil}// EncodeToBase64 encodes byte slice to base64 stringfunc EncodeToBase64(data []byte) string {	return base64.StdEncoding.EncodeToString(data)}// DecodeFromBase64 decodes base64 string to byte slicefunc DecodeFromBase64(encoded string) ([]byte, error) {	return base64.StdEncoding.DecodeString(encoded)}
 |