Skip to content

Commit

Permalink
Add CLI functionality + update README/output dir
Browse files Browse the repository at this point in the history
  • Loading branch information
theognis1002 committed Feb 20, 2025
1 parent da31d88 commit 7db5308
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 105 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ Temporary Items

# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
.env
go-encrypt
output/*
!output/.gitkeep
38 changes: 14 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,41 +1,31 @@
### Makefile
.PHONY: encrypt decrypt clean test all

```Makefile
# Makefile for the Go File Encryption and Decryption project
KEY = 1234567890123456
INPUT_FILE = example.csv
OUTPUT_DIR = output

# The binary name
BINARY_NAME = file-crypto

# Build the Go binary
build:
@echo "Building the Go binary..."
go build -o $(BINARY_NAME) main.go

# Run the Go application with encryption
encrypt:
@echo "Encrypting the file..."
./$(BINARY_NAME) encrypt example.csv encrypted.csv
@mkdir -p $(OUTPUT_DIR)
go run main.go -key "$(KEY)" -input "$(INPUT_FILE)" -encrypt "encrypted.csv"

# Run the Go application with decryption
decrypt:
@echo "Decrypting the file..."
./$(BINARY_NAME) decrypt encrypted.csv decrypted.csv
@mkdir -p $(OUTPUT_DIR)
go run main.go -key "$(KEY)" -input "$(OUTPUT_DIR)/encrypted.csv" -decrypt "decrypted.csv"

# Clean up build files
clean:
@echo "Cleaning up..."
rm -f $(BINARY_NAME)
@find $(OUTPUT_DIR)/ -type f ! -name '.gitkeep' -delete
@echo "Squeaky clean!"

# Run all tests
test:
@echo "Running tests..."
go test -v ./...

# Run tests with coverage
test-coverage:
@echo "Running tests with coverage..."
go test -v -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
@mkdir -p $(OUTPUT_DIR)
go test -v -coverprofile=$(OUTPUT_DIR)/coverage.out ./...
go tool cover -html=$(OUTPUT_DIR)/coverage.out -o $(OUTPUT_DIR)/coverage.html

# Default target: build the binary and run tests
all: build test
all: test
78 changes: 25 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,27 @@
# Multi-Algorithm File Encryption & Decryption in Go

This project provides a robust implementation of file encryption and decryption using multiple encryption algorithms in Go. It supports AES-GCM, DES-CBC, and RC4 encryption methods.
This project provides a robust implementation of file encryption and decryption using AES-GCM in Go.

## Features

- Multiple encryption algorithms:
- AES (Advanced Encryption Standard) with GCM mode
- DES (Data Encryption Standard) with CBC mode
- RC4 (Rivest Cipher 4) stream cipher
- AES (Advanced Encryption Standard) with GCM mode
- Secure key handling
- File-based encryption/decryption
- Environment variable configuration
- Command-line interface
- Makefile support

## Requirements

- Go 1.21 or later
- Environment variables configuration

## Supported Algorithms
## Supported Algorithm

### AES (Advanced Encryption Standard)

- Key size: 16 bytes (AES-128)
- Modern, secure block cipher
- Recommended for most use cases
- Uses GCM mode for authenticated encryption

### DES (Data Encryption Standard)

- Key size: 8 bytes
- Legacy block cipher
- Not recommended for new applications
- Uses CBC mode with PKCS7 padding

### RC4 (Rivest Cipher 4)

- Variable key size (using 16 bytes in this implementation)
- Stream cipher
- Fast but not cryptographically secure
- Not recommended for sensitive data
- Recommended for secure data encryption

## Usage

Expand All @@ -51,23 +34,6 @@ This project provides a robust implementation of file encryption and decryption
cd go-encrypt/
```

2. **Configure the environment:**
Create a `.env` file with the following variables:

```
ALGORITHM=AES # Can be AES, DES, or RC4
KEY=your16bytesecret # Key size depends on algorithm
INPUT_FILE=example.txt
ENCRYPTED_FILE=encrypted.bin
DECRYPTED_FILE=decrypted.txt
```

Key size requirements:

- AES: 16 bytes
- DES: 8 bytes
- RC4: 16 bytes

### Running the Program

1. **Build the program:**
Expand All @@ -87,32 +53,38 @@ This project provides a robust implementation of file encryption and decryption
make decrypt
```

### Example Usage
### Command Line Options

1. **Using AES encryption:**
The program supports the following flags:

```sh
ALGORITHM=AES KEY=1234567890123456 make encrypt
```
```sh
-key string 16-byte encryption/decryption key
-input string input file path
-encrypt string output path for encrypted file
-decrypt string output path for decrypted file
```

2. **Using DES encryption:**
### Example Usage

1. **Direct command line usage:**

```sh
ALGORITHM=DES KEY=12345678 make encrypt
./go-encrypt -key "1234567890123456" -input "example.txt" -encrypt "encrypted.bin"
./go-encrypt -key "1234567890123456" -input "encrypted.bin" -decrypt "decrypted.txt"
```

3. **Using RC4 encryption:**
2. **Using Makefile (with default values):**

```sh
ALGORITHM=RC4 KEY=1234567890123456 make encrypt
make encrypt # Uses KEY=1234567890123456 and INPUT_FILE=example.csv
make decrypt
```

## Security Considerations

- AES is the recommended algorithm for new applications
- DES is included for legacy compatibility but should not be used for new applications
- RC4 is included for educational purposes but should not be used for sensitive data
- Always use strong, random keys
- Always use strong, random keys (16 bytes for AES-128)
- Keep your keys secure and never commit them to version control
- The implementation uses AES-GCM which provides both confidentiality and authenticity

## Contributing

Expand Down
78 changes: 50 additions & 28 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,66 @@ import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"flag"
"fmt"
"io"
"log"
"os"

"github.com/joho/godotenv"
"path/filepath"
)

func main() {
// Load the environment variables from the .env file
err := godotenv.Load()
if err != nil {
log.Fatalf("Error loading .env file")
keyPtr := flag.String("key", "", "16-byte encryption/decryption key")
inputPtr := flag.String("input", "", "input file path")
encryptPtr := flag.String("encrypt", "", "output path for encrypted file")
decryptPtr := flag.String("decrypt", "", "output path for decrypted file")

flag.Parse()

// Validate required flags
if *keyPtr == "" || *inputPtr == "" || (*encryptPtr == "" && *decryptPtr == "") {
flag.Usage()
log.Fatalf("Missing required flags")
}

key := []byte(os.Getenv("KEY"))
inputFile := os.Getenv("INPUT_FILE")
encryptedFile := os.Getenv("ENCRYPTED_FILE")
decryptedFile := os.Getenv("DECRYPTED_FILE")
key := []byte(*keyPtr)
inputFile := *inputPtr

// Check if the key length is correct
if len(key) != 16 {
log.Fatalf("Key length must be 16 bytes")
}

err := os.MkdirAll("output", 0755)
if err != nil {
log.Fatalf("Error creating output directory: %v", err)
}

fmt.Println("Key:", string(key))
fmt.Println("Input File:", inputFile)
fmt.Println("Encrypted File:", encryptedFile)
fmt.Println("Decrypted File:", decryptedFile)

// Encrypt the file
err = encryptFile(inputFile, encryptedFile, key)
if err != nil {
fmt.Println("Error encrypting file:", err)
return
if *encryptPtr != "" {
outputPath := filepath.Join("output", *encryptPtr)
err = encryptFile(inputFile, outputPath, key)
if err != nil {
fmt.Println("Error encrypting file:", err)
return
}
fmt.Println("File encrypted successfully to:", outputPath)
}
fmt.Println("File encrypted successfully.")

// Decrypt the file
err = decryptFile(encryptedFile, decryptedFile, key)
if err != nil {
fmt.Println("Error decrypting file:", err)
return
if *decryptPtr != "" {
inputForDecrypt := inputFile
if *encryptPtr != "" {
inputForDecrypt = filepath.Join("output", *encryptPtr)
}
outputPath := filepath.Join("output", *decryptPtr)
err = decryptFile(inputForDecrypt, outputPath, key)
if err != nil {
fmt.Println("Error decrypting file:", err)
return
}
fmt.Println("File decrypted successfully to:", outputPath)
}
fmt.Println("File decrypted successfully.")
}

// encryptFile encrypts the file at inputPath and writes the encrypted data to outputPath
Expand All @@ -58,7 +73,6 @@ func encryptFile(inputPath, outputPath string, key []byte) error {
return err
}

// Generate a new AES cipher using our 16, 24 or 32 bytes long key
block, err := aes.NewCipher(key)
if err != nil {
return err
Expand All @@ -74,9 +88,13 @@ func encryptFile(inputPath, outputPath string, key []byte) error {
return err
}

// Encrypt the data using Seal (which also appends the nonce and the encrypted data together)
ciphertext := gcm.Seal(nonce, nonce, data, nil)

// Create output directory if it doesn't exist
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
return err
}

return os.WriteFile(outputPath, ciphertext, 0644)
}

Expand All @@ -100,11 +118,15 @@ func decryptFile(inputPath, outputPath string, key []byte) error {
nonceSize := gcm.NonceSize()
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]

// Decrypt the data
plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return err
}

// Create output directory if it doesn't exist
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
return err
}

return os.WriteFile(outputPath, plaintext, 0644)
}
Empty file added output/.gitkeep
Empty file.

0 comments on commit 7db5308

Please sign in to comment.