File Encryption Management on macOS
Secure sensitive data across your MacFleet devices using advanced file encryption and decryption techniques. This tutorial covers OpenSSL encryption methods, enterprise key management, security policies, and compliance monitoring for comprehensive data protection.
Understanding File Encryption on macOS
File encryption protects sensitive data by converting it into an unreadable format that can only be accessed with the correct decryption key. While macOS offers FileVault for full-disk encryption, selective file encryption provides granular control over specific documents and data files.
Key Encryption Methods
- DES (Data Encryption Standard) - Legacy encryption for basic protection
- AES-256-CBC - Advanced Encryption Standard with 256-bit keys
- AES-256-GCM - AES with Galois/Counter Mode for authenticated encryption
- ChaCha20-Poly1305 - Modern stream cipher with authentication
- RSA - Public-key encryption for key exchange and digital signatures
Basic File Encryption
Simple File Encryption
#!/bin/bash
# Basic file encryption using OpenSSL
INPUT_FILE="/path/to/original.txt"
OUTPUT_FILE="/path/to/encrypted.txt"
PASSWORD="your_secure_password"
openssl des -in "$INPUT_FILE" -out "$OUTPUT_FILE" -k "$PASSWORD"
echo "File encrypted successfully: $OUTPUT_FILE"
Enhanced File Encryption
#!/bin/bash
# Enhanced file encryption with validation
encrypt_file() {
local input_file="$1"
local output_file="$2"
local password="$3"
local algorithm="${4:-aes-256-cbc}"
# Validate input parameters
if [[ -z "$input_file" ]] || [[ -z "$output_file" ]] || [[ -z "$password" ]]; then
echo "❌ Error: Missing required parameters"
echo "Usage: encrypt_file <input_file> <output_file> <password> [algorithm]"
return 1
fi
# Check if input file exists
if [[ ! -f "$input_file" ]]; then
echo "❌ Error: Input file does not exist: $input_file"
return 1
fi
# Create output directory if it doesn't exist
local output_dir
output_dir=$(dirname "$output_file")
mkdir -p "$output_dir"
echo "🔒 Encrypting file with $algorithm..."
echo " Input: $input_file"
echo " Output: $output_file"
# Perform encryption
if openssl "$algorithm" -in "$input_file" -out "$output_file" -k "$password" 2>/dev/null; then
echo "✅ File encrypted successfully"
# Verify encrypted file was created
if [[ -f "$output_file" ]]; then
local file_size
file_size=$(stat -f%z "$output_file" 2>/dev/null || echo "0")
echo " Encrypted file size: ${file_size} bytes"
fi
return 0
else
echo "❌ Encryption failed"
return 1
fi
}
# Usage examples
encrypt_file "/Users/john/Documents/sensitive.txt" "/Users/john/Encrypted/sensitive.enc" "mypassword123" "aes-256-cbc"
AES-256 Strong Encryption
#!/bin/bash
# Advanced AES-256-CBC encryption with salt
encrypt_file_aes256() {
local input_file="$1"
local output_file="$2"
local password="$3"
echo "🔐 Performing AES-256-CBC encryption..."
# Use AES-256-CBC with salt for enhanced security
if openssl aes-256-cbc -salt -in "$input_file" -out "$output_file" -k "$password"; then
echo "✅ AES-256 encryption completed"
# Generate file hash for integrity verification
local hash
hash=$(shasum -a 256 "$output_file" | cut -d' ' -f1)
echo " File hash (SHA-256): $hash"
# Save hash for verification
echo "$hash" > "${output_file}.sha256"
echo " Hash saved to: ${output_file}.sha256"
return 0
else
echo "❌ AES-256 encryption failed"
return 1
fi
}
# Example usage
encrypt_file_aes256 "/path/to/document.pdf" "/path/to/document.pdf.enc" "strong_password_123!"
File Decryption
Basic File Decryption
#!/bin/bash
# Basic file decryption using OpenSSL
INPUT_FILE="/path/to/encrypted.txt"
OUTPUT_FILE="/path/to/decrypted.txt"
PASSWORD="your_secure_password"
openssl des -d -in "$INPUT_FILE" -out "$OUTPUT_FILE" -k "$PASSWORD"
echo "File decrypted successfully: $OUTPUT_FILE"
Advanced File Decryption
#!/bin/bash
# Advanced file decryption with verification
decrypt_file() {
local input_file="$1"
local output_file="$2"
local password="$3"
local algorithm="${4:-aes-256-cbc}"
# Validate parameters
if [[ -z "$input_file" ]] || [[ -z "$output_file" ]] || [[ -z "$password" ]]; then
echo "❌ Error: Missing required parameters"
echo "Usage: decrypt_file <input_file> <output_file> <password> [algorithm]"
return 1
fi
# Check if encrypted file exists
if [[ ! -f "$input_file" ]]; then
echo "❌ Error: Encrypted file does not exist: $input_file"
return 1
fi
echo "🔓 Decrypting file with $algorithm..."
echo " Input: $input_file"
echo " Output: $output_file"
# Create output directory
local output_dir
output_dir=$(dirname "$output_file")
mkdir -p "$output_dir"
# Perform decryption
if openssl "$algorithm" -d -in "$input_file" -out "$output_file" -k "$password" 2>/dev/null; then
echo "✅ File decrypted successfully"
# Verify hash if available
verify_file_integrity "$input_file" "$output_file"
return 0
else
echo "❌ Decryption failed - incorrect password or corrupted file"
return 1
fi
}
# Verify file integrity
verify_file_integrity() {
local encrypted_file="$1"
local decrypted_file="$2"
local hash_file="${encrypted_file}.sha256"
if [[ -f "$hash_file" ]]; then
echo "🔍 Verifying file integrity..."
local stored_hash expected_hash
stored_hash=$(cat "$hash_file")
# For verification, we need the original file hash (this is a simplified example)
if [[ -f "$decrypted_file" ]]; then
echo " File integrity check completed"
fi
fi
}
# Usage example
decrypt_file "/path/to/document.pdf.enc" "/path/to/document_recovered.pdf" "strong_password_123!" "aes-256-cbc"
Batch File Operations
Encrypt Multiple Files
#!/bin/bash
# Batch encrypt multiple files
batch_encrypt() {
local source_dir="$1"
local encrypted_dir="$2"
local password="$3"
local file_pattern="${4:-*}"
echo "📁 Batch encryption starting..."
echo " Source: $source_dir"
echo " Target: $encrypted_dir"
echo " Pattern: $file_pattern"
# Create encrypted directory
mkdir -p "$encrypted_dir"
local count=0
local success=0
# Process files matching pattern
while IFS= read -r -d '' file; do
if [[ -f "$file" ]]; then
local relative_path
relative_path=$(realpath --relative-to="$source_dir" "$file")
local encrypted_file="$encrypted_dir/${relative_path}.enc"
# Create subdirectories if needed
mkdir -p "$(dirname "$encrypted_file")"
echo " Processing: $relative_path"
if openssl aes-256-cbc -salt -in "$file" -out "$encrypted_file" -k "$password" 2>/dev/null; then
((success++))
echo " ✅ Encrypted"
else
echo " ❌ Failed"
fi
((count++))
fi
done < <(find "$source_dir" -name "$file_pattern" -type f -print0)
echo "🎉 Batch encryption completed: $success/$count files encrypted"
}
# Usage example
batch_encrypt "/Users/john/Documents" "/Users/john/Encrypted" "batch_password123" "*.txt"
Decrypt Multiple Files
#!/bin/bash
# Batch decrypt multiple files
batch_decrypt() {
local encrypted_dir="$1"
local output_dir="$2"
local password="$3"
echo "📂 Batch decryption starting..."
echo " Source: $encrypted_dir"
echo " Target: $output_dir"
# Create output directory
mkdir -p "$output_dir"
local count=0
local success=0
# Process .enc files
while IFS= read -r -d '' file; do
if [[ -f "$file" && "$file" == *.enc ]]; then
local relative_path
relative_path=$(realpath --relative-to="$encrypted_dir" "$file")
# Remove .enc extension
local decrypted_file="$output_dir/${relative_path%.enc}"
# Create subdirectories if needed
mkdir -p "$(dirname "$decrypted_file")"
echo " Processing: $relative_path"
if openssl aes-256-cbc -d -in "$file" -out "$decrypted_file" -k "$password" 2>/dev/null; then
((success++))
echo " ✅ Decrypted"
else
echo " ❌ Failed"
fi
((count++))
fi
done < <(find "$encrypted_dir" -name "*.enc" -type f -print0)
echo "🎉 Batch decryption completed: $success/$count files decrypted"
}
# Usage example
batch_decrypt "/Users/john/Encrypted" "/Users/john/Decrypted" "batch_password123"
Enterprise Encryption Management Script
#!/bin/bash
# MacFleet File Encryption Management System
# Comprehensive encryption/decryption management for enterprise environments
# Configuration
LOG_FILE="/var/log/macfleet_encryption.log"
CONFIG_FILE="/etc/macfleet/encryption_policy.conf"
KEY_STORE="/var/lib/macfleet/keys"
AUDIT_LOG="/var/log/macfleet_encryption_audit.log"
# Logging function
log_action() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Audit logging
audit_log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$AUDIT_LOG"
}
# Setup environment
setup_environment() {
sudo mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null
sudo mkdir -p "$(dirname "$CONFIG_FILE")" 2>/dev/null
sudo mkdir -p "$KEY_STORE" 2>/dev/null
sudo chmod 700 "$KEY_STORE" 2>/dev/null
}
# Load configuration
load_config() {
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
log_action "Configuration loaded from $CONFIG_FILE"
else
# Default configuration
DEFAULT_ALGORITHM="aes-256-cbc"
REQUIRE_STRONG_PASSWORDS=true
MIN_PASSWORD_LENGTH=12
ENCRYPTION_ENABLED=true
AUTO_BACKUP_KEYS=true
COMPLIANCE_MODE="HIPAA" # HIPAA, PCI-DSS, GDPR
log_action "Using default encryption configuration"
fi
}
# Validate password strength
validate_password() {
local password="$1"
if [[ "$REQUIRE_STRONG_PASSWORDS" != "true" ]]; then
return 0
fi
# Check minimum length
if [[ ${#password} -lt $MIN_PASSWORD_LENGTH ]]; then
echo "❌ Password too short (minimum $MIN_PASSWORD_LENGTH characters)"
return 1
fi
# Check complexity
local has_upper has_lower has_digit has_special
has_upper=$(echo "$password" | grep -c '[A-Z]')
has_lower=$(echo "$password" | grep -c '[a-z]')
has_digit=$(echo "$password" | grep -c '[0-9]')
has_special=$(echo "$password" | grep -c '[^A-Za-z0-9]')
if [[ $has_upper -eq 0 ]] || [[ $has_lower -eq 0 ]] || [[ $has_digit -eq 0 ]] || [[ $has_special -eq 0 ]]; then
echo "❌ Password must contain uppercase, lowercase, digit, and special character"
return 1
fi
return 0
}
# Generate secure key
generate_secure_key() {
local key_name="$1"
local key_file="$KEY_STORE/${key_name}.key"
# Generate random 256-bit key
openssl rand -base64 32 > "$key_file"
chmod 600 "$key_file"
log_action "Generated secure key: $key_name"
audit_log "KEY_GENERATED: $key_name by $(whoami)"
echo "$key_file"
}
# Encrypt file with enterprise features
enterprise_encrypt() {
local input_file="$1"
local output_file="$2"
local key_name="$3"
local algorithm="${4:-$DEFAULT_ALGORITHM}"
if [[ "$ENCRYPTION_ENABLED" != "true" ]]; then
echo "❌ Encryption is disabled by policy"
return 1
fi
# Validate input file
if [[ ! -f "$input_file" ]]; then
echo "❌ Input file not found: $input_file"
return 1
fi
# Get or generate key
local key_file="$KEY_STORE/${key_name}.key"
if [[ ! -f "$key_file" ]]; then
echo "🔑 Generating new encryption key: $key_name"
generate_secure_key "$key_name"
fi
local password
password=$(cat "$key_file")
echo "🔒 Enterprise encryption starting..."
echo " Algorithm: $algorithm"
echo " Input: $input_file"
echo " Output: $output_file"
echo " Key: $key_name"
# Create metadata file
local metadata_file="${output_file}.meta"
cat > "$metadata_file" << EOF
{
"algorithm": "$algorithm",
"key_name": "$key_name",
"encrypted_by": "$(whoami)",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"hostname": "$(hostname)",
"compliance_mode": "$COMPLIANCE_MODE",
"file_size": $(stat -f%z "$input_file"),
"original_name": "$(basename "$input_file")"
}
EOF
# Perform encryption
if openssl "$algorithm" -salt -in "$input_file" -out "$output_file" -pass file:"$key_file"; then
# Generate integrity hash
local hash
hash=$(shasum -a 256 "$output_file" | cut -d' ' -f1)
echo " \"integrity_hash\": \"$hash\"" >> "$metadata_file"
log_action "File encrypted: $input_file -> $output_file (key: $key_name)"
audit_log "ENCRYPT: $input_file -> $output_file by $(whoami) using $key_name"
echo "✅ Enterprise encryption completed"
echo " Metadata: $metadata_file"
# Backup key if enabled
if [[ "$AUTO_BACKUP_KEYS" == "true" ]]; then
backup_key "$key_name"
fi
return 0
else
echo "❌ Encryption failed"
log_action "Encryption failed: $input_file"
return 1
fi
}
# Decrypt file with enterprise features
enterprise_decrypt() {
local input_file="$1"
local output_file="$2"
local key_name="$3"
# Check if encrypted file exists
if [[ ! -f "$input_file" ]]; then
echo "❌ Encrypted file not found: $input_file"
return 1
fi
# Load metadata
local metadata_file="${input_file}.meta"
if [[ ! -f "$metadata_file" ]]; then
echo "⚠️ Metadata file not found, using default algorithm"
local algorithm="$DEFAULT_ALGORITHM"
else
local algorithm
algorithm=$(grep '"algorithm"' "$metadata_file" | cut -d'"' -f4)
echo "📋 Loaded metadata: algorithm=$algorithm"
fi
# Get key
local key_file="$KEY_STORE/${key_name}.key"
if [[ ! -f "$key_file" ]]; then
echo "❌ Decryption key not found: $key_name"
return 1
fi
echo "🔓 Enterprise decryption starting..."
echo " Algorithm: $algorithm"
echo " Input: $input_file"
echo " Output: $output_file"
echo " Key: $key_name"
# Perform decryption
if openssl "$algorithm" -d -in "$input_file" -out "$output_file" -pass file:"$key_file"; then
# Verify integrity if hash available
if [[ -f "$metadata_file" ]]; then
verify_integrity "$input_file" "$metadata_file"
fi
log_action "File decrypted: $input_file -> $output_file (key: $key_name)"
audit_log "DECRYPT: $input_file -> $output_file by $(whoami) using $key_name"
echo "✅ Enterprise decryption completed"
return 0
else
echo "❌ Decryption failed"
log_action "Decryption failed: $input_file"
audit_log "DECRYPT_FAILED: $input_file by $(whoami)"
return 1
fi
}
# Verify file integrity
verify_integrity() {
local encrypted_file="$1"
local metadata_file="$2"
if [[ -f "$metadata_file" ]]; then
local stored_hash current_hash
stored_hash=$(grep '"integrity_hash"' "$metadata_file" | cut -d'"' -f4)
current_hash=$(shasum -a 256 "$encrypted_file" | cut -d' ' -f1)
if [[ "$stored_hash" == "$current_hash" ]]; then
echo "✅ File integrity verified"
else
echo "⚠️ File integrity check failed - file may be corrupted"
log_action "Integrity check failed: $encrypted_file"
fi
fi
}
# Backup encryption key
backup_key() {
local key_name="$1"
local key_file="$KEY_STORE/${key_name}.key"
local backup_dir="$KEY_STORE/backups"
mkdir -p "$backup_dir"
local backup_file="$backup_dir/${key_name}_$(date +%Y%m%d_%H%M%S).key"
cp "$key_file" "$backup_file"
log_action "Key backed up: $key_name -> $backup_file"
}
# Generate encryption report
generate_encryption_report() {
local report_file="/tmp/macfleet_encryption_report_$(date +%Y%m%d_%H%M%S).txt"
{
echo "MacFleet Encryption Management Report"
echo "===================================="
echo "Generated: $(date)"
echo "Hostname: $(hostname)"
echo "Compliance Mode: $COMPLIANCE_MODE"
echo ""
echo "Configuration:"
echo " Default Algorithm: $DEFAULT_ALGORITHM"
echo " Strong Passwords: $REQUIRE_STRONG_PASSWORDS"
echo " Min Password Length: $MIN_PASSWORD_LENGTH"
echo " Encryption Enabled: $ENCRYPTION_ENABLED"
echo ""
echo "Available Keys:"
if ls "$KEY_STORE"/*.key >/dev/null 2>&1; then
for key_file in "$KEY_STORE"/*.key; do
local key_name
key_name=$(basename "$key_file" .key)
echo " $key_name ($(stat -f%Sm "$key_file"))"
done
else
echo " No keys found"
fi
echo ""
echo "Recent Encryption Activity:"
if [[ -f "$AUDIT_LOG" ]]; then
tail -10 "$AUDIT_LOG"
else
echo " No activity logged"
fi
} > "$report_file"
echo "📄 Encryption report generated: $report_file"
log_action "Report generated: $report_file"
}
# Main function
main() {
case "${1:-status}" in
"encrypt")
setup_environment
load_config
log_action "=== File Encryption Request ==="
enterprise_encrypt "$2" "$3" "$4" "$5"
;;
"decrypt")
setup_environment
load_config
log_action "=== File Decryption Request ==="
enterprise_decrypt "$2" "$3" "$4"
;;
"generate-key")
setup_environment
load_config
log_action "=== Key Generation Request ==="
generate_secure_key "$2"
;;
"report")
setup_environment
load_config
generate_encryption_report
;;
"list-algorithms")
echo "📋 Available encryption algorithms:"
openssl list-cipher-commands | tr ' ' '\n' | sort
;;
"status"|*)
setup_environment
load_config
echo "📊 MacFleet Encryption Status:"
echo "=============================="
echo "Encryption Enabled: $ENCRYPTION_ENABLED"
echo "Default Algorithm: $DEFAULT_ALGORITHM"
echo "Compliance Mode: $COMPLIANCE_MODE"
echo "Key Store: $KEY_STORE"
if ls "$KEY_STORE"/*.key >/dev/null 2>&1; then
echo "Available Keys: $(ls "$KEY_STORE"/*.key | wc -l)"
else
echo "Available Keys: 0"
fi
;;
esac
}
# Execute main function with parameters
main "$@"
Encryption Algorithms Reference
Quick Comparison
Algorithm | Key Size | Security | Performance | Use Case |
---|---|---|---|---|
DES | 56-bit | Low | Fast | Legacy systems only |
AES-128-CBC | 128-bit | Good | Fast | General purpose |
AES-256-CBC | 256-bit | Excellent | Medium | High security |
AES-256-GCM | 256-bit | Excellent | Medium | Authenticated encryption |
ChaCha20 | 256-bit | Excellent | Fast | Modern alternative |
List Available Algorithms
# Display all available encryption algorithms
openssl list-cipher-commands
# Common secure algorithms
openssl enc -ciphers | grep -E "(aes|chacha)"
Security Best Practices
Password Management
#!/bin/bash
# Generate secure password
generate_secure_password() {
local length="${1:-16}"
# Generate password with mixed characters
openssl rand -base64 "$length" | tr -d "=+/" | cut -c1-"$length"
}
# Example: Generate 20-character password
secure_password=$(generate_secure_password 20)
echo "Generated password: $secure_password"
Key Rotation
#!/bin/bash
# Rotate encryption keys
rotate_encryption_key() {
local old_key="$1"
local new_key="$2"
local files_dir="$3"
echo "🔄 Rotating encryption key: $old_key -> $new_key"
# Generate new key
generate_secure_key "$new_key"
# Re-encrypt files with new key
while IFS= read -r -d '' file; do
if [[ "$file" == *.enc ]]; then
local temp_file="/tmp/temp_decrypt_$$"
# Decrypt with old key
if enterprise_decrypt "$file" "$temp_file" "$old_key"; then
# Re-encrypt with new key
if enterprise_encrypt "$temp_file" "$file" "$new_key"; then
echo " ✅ Rotated: $(basename "$file")"
fi
fi
# Clean up
rm -f "$temp_file"
fi
done < <(find "$files_dir" -name "*.enc" -type f -print0)
echo "🎉 Key rotation completed"
}
Troubleshooting
Common Issues
-
Encryption fails with "bad decrypt"
- Verify correct algorithm is used
- Check password/key file integrity
- Ensure sufficient disk space
-
Permission denied errors
- Check file permissions
- Verify key store access rights
- Run with appropriate user privileges
-
Corrupted encrypted files
- Verify file integrity hashes
- Check for disk errors
- Restore from backups if available
Verification Commands
# Test encryption/decryption cycle
test_encryption() {
local test_file="/tmp/test_encrypt.txt"
local encrypted_file="/tmp/test_encrypt.enc"
local decrypted_file="/tmp/test_decrypt.txt"
# Create test file
echo "This is a test file for encryption" > "$test_file"
# Encrypt
openssl aes-256-cbc -in "$test_file" -out "$encrypted_file" -k "testpassword"
# Decrypt
openssl aes-256-cbc -d -in "$encrypted_file" -out "$decrypted_file" -k "testpassword"
# Compare
if diff "$test_file" "$decrypted_file" >/dev/null; then
echo "✅ Encryption/decryption test passed"
else
echo "❌ Encryption/decryption test failed"
fi
# Cleanup
rm -f "$test_file" "$encrypted_file" "$decrypted_file"
}
Important Notes
- Algorithm selection: Use AES-256-CBC or stronger for sensitive data
- Password security: Implement strong password policies for enterprise use
- Key management: Securely store and backup encryption keys
- Compliance: Ensure encryption methods meet regulatory requirements
- Performance: Consider file size and system resources when choosing algorithms
- Backup strategy: Always maintain secure backups of encryption keys
Enterprise Deployment
For enterprise deployment, consider:
- Policy definition - Establish encryption standards and procedures
- Key management - Implement secure key storage and rotation
- Compliance monitoring - Ensure adherence to regulatory requirements
- User training - Educate users on proper encryption practices
- Audit trails - Maintain comprehensive logs of encryption activities