From 72339bf39050f28ff5624169dfa6e7781f16a682 Mon Sep 17 00:00:00 2001 From: Abdiooa Date: Tue, 6 Feb 2024 22:42:06 +0300 Subject: [PATCH] added datapreparation for aes for big size files --- cmd/zeroward/decrypt.go | 2 +- pkg/zeroward/decryption/decrypt.go | 66 +++++++++++++++++++++--------- pkg/zeroward/encryption/encrypt.go | 43 ++++++++++++------- 3 files changed, 75 insertions(+), 36 deletions(-) diff --git a/cmd/zeroward/decrypt.go b/cmd/zeroward/decrypt.go index ee5aa02..5901436 100644 --- a/cmd/zeroward/decrypt.go +++ b/cmd/zeroward/decrypt.go @@ -37,7 +37,7 @@ var decryptCmd = &cobra.Command{ if filePath != "" { if err := decryption.DecryptFile(filePath, dekkey); err != nil { - fmt.Println("Error encrypting File:", err) + fmt.Println("Error Decrypting File:", err) return } } diff --git a/pkg/zeroward/decryption/decrypt.go b/pkg/zeroward/decryption/decrypt.go index 24c7d3c..c6b5ae9 100644 --- a/pkg/zeroward/decryption/decrypt.go +++ b/pkg/zeroward/decryption/decrypt.go @@ -3,7 +3,9 @@ package decryption import ( "crypto/aes" "crypto/cipher" + "encoding/binary" "fmt" + "hash/crc32" "os" ) @@ -22,33 +24,40 @@ func DecryptKey(encryptedKeyFile string, kekKey []byte) ([]byte, error) { return decryptedKey, nil } + func DecryptFile(cipherFile string, dekKey []byte) error { ciphertext, err := os.ReadFile(cipherFile) if err != nil { return fmt.Errorf("error reading ciphertext file: %v", err) } - // Use the KEK key to decrypt the DEK key - decryptedData, err := DecryptData(ciphertext, dekKey) - if err != nil { - return err + blockSize := 1024 + 4 + 16 + 12 // Include space for checksum + var decryptedData []byte + + for i := 0; i < len(ciphertext); i += blockSize { + end := i + blockSize + if end > len(ciphertext) { + end = len(ciphertext) + } + block := ciphertext[i:end] + // Decrypt each block + decryptedBlock, err := DecryptData(block, dekKey) + if err != nil { + return err + } + originalData, err := VerifyChecksum(decryptedBlock) + if err != nil { + return err + } + decryptedData = append(decryptedData, originalData...) } - if err := os.Remove(cipherFile); err != nil { return err } - // Remove the ".enc" extension from the file name decryptedFilePath := cipherFile[:len(cipherFile)-4] - dstFile, err := os.Create(decryptedFilePath) - if err != nil { - return err - } - defer dstFile.Close() - - _, err = dstFile.Write(decryptedData) - if err != nil { + if err := os.WriteFile(decryptedFilePath, decryptedData, 0644); err != nil { return err } @@ -61,26 +70,43 @@ func DecryptData(ciphertext, key []byte) ([]byte, error) { return nil, fmt.Errorf("error creating AES cipher: %v", err) } - // Create a GCM mode gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } - // Extract nonce and actual ciphertext nonceSize := gcm.NonceSize() if len(ciphertext) < nonceSize { return nil, fmt.Errorf("ciphertext is too short") } - nonce := ciphertext[:nonceSize] - actualCiphertext := ciphertext[nonceSize:] + nonce, actualCiphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] - // Decrypt the ciphertext plaintext, err := gcm.Open(nil, nonce, actualCiphertext, nil) if err != nil { - return nil, err + return nil, fmt.Errorf("error decrypting: %v", err) } return plaintext, nil } + +func VerifyChecksum(data []byte) ([]byte, error) { + blockSize := 1024 + var originalData []byte + for i := 0; i < len(data); i += blockSize + 4 { // the 4 bytes for checksum bytes + end := i + blockSize + 4 + if end > len(data) { + end = len(data) + } + blockWithChecksum := data[i:end] + checksumBytes := blockWithChecksum[:4] + block := blockWithChecksum[4:] + // verify checksum + checksum := crc32.ChecksumIEEE(block) + if binary.BigEndian.Uint32(checksumBytes) != checksum { + return nil, fmt.Errorf("checksum verification failed") + } + originalData = append(originalData, block...) + } + return originalData, nil +} diff --git a/pkg/zeroward/encryption/encrypt.go b/pkg/zeroward/encryption/encrypt.go index 7467568..cac1511 100644 --- a/pkg/zeroward/encryption/encrypt.go +++ b/pkg/zeroward/encryption/encrypt.go @@ -1,10 +1,12 @@ package encryption import ( + "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" - "fmt" + "encoding/binary" + "hash/crc32" "io" "os" "path/filepath" @@ -16,10 +18,7 @@ func EncryptKey(dek []byte, kek []byte, filePath string) error { return err } - // Extract directory part of filePath outputDEKDir := filepath.Dir(filePath) - - // Create encrypted DEK file path by joining the directory and the new filename outputDEKFilePath := filepath.Join(outputDEKDir, "DEK.key.enc") file, err := os.Create(outputDEKFilePath) @@ -52,18 +51,34 @@ func EncryptFile(filePath string, dek []byte) error { return err } - encryptedData, err := EncryptData(plaintext, dek) - if err != nil { - return err + blockSize := 1024 + var encryptedBlocks [][]byte + for i := 0; i < len(plaintext); i += blockSize { + end := i + blockSize + if end > len(plaintext) { + end = len(plaintext) + } + block := plaintext[i:end] + + checksum := crc32.ChecksumIEEE(block) + checksumBytes := make([]byte, 4) + binary.BigEndian.PutUint32(checksumBytes, checksum) + checksumBlock := append(checksumBytes, block...) + + encryptedBlock, err := EncryptData(checksumBlock, dek) + if err != nil { + return err + } + encryptedBlocks = append(encryptedBlocks, encryptedBlock) } - // Remove the plaintext from the file + encryptedData := bytes.Join(encryptedBlocks, nil) + if err := os.Remove(filePath); err != nil { return err } - outputFilePath := fmt.Sprintf("%s.enc", filePath) - + outputFilePath := filePath + ".enc" dstFile, err := os.Create(outputFilePath) if err != nil { return err @@ -77,8 +92,8 @@ func EncryptFile(filePath string, dek []byte) error { return nil } -func EncryptData(data []byte, key []byte) ([]byte, error) { +func EncryptData(data []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err @@ -90,12 +105,10 @@ func EncryptData(data []byte, key []byte) ([]byte, error) { } nonce := make([]byte, gcm.NonceSize()) - if _, err := rand.Read(nonce); err != nil { return nil, err } + ciphertext := gcm.Seal(nonce, nonce, data, nil) - // Concatenate ciphertext and nonce - result := ciphertext - return result, nil + return ciphertext, nil }