A CLI tool for securely encrypting and decrypting .env files using AES-256-GCM encryption with optional custom obfuscation.
- AES-256-GCM encryption with randomly generated 12-byte IV
- Authentication tags for data integrity verification
- Custom obfuscation layer (XOR + byte shuffling) before AES encryption
- 256-bit encryption keys stored as Base64 in local key files
- Content integrity checks with SHA-256 checksums
- Metadata tracking (timestamp, size, checksum) in encrypted files
- Smart .gitignore management - automatically updates your .gitignore
- Simple naming - always encrypts to
voynich.encrypted
This tool is designed for development use only and should not be considered a replacement for a full secrets management system in production environments. While it uses strong encryption (AES-256-GCM), proper secrets management in production requires additional security measures, access controls, and infrastructure that this tool does not provide.
# No installation needed! Use directly with npx
npx devdotenv init
npx devdotenv encrypt .env
npx devdotenv decryptnpm install devdotenv
npx devdotenv initgit clone https://github.com/guinat/devdotenv-node.git
cd devdotenv-node
npm install
npm link # Makes 'devdotenv' command available globally-
Initialize encryption key and setup .gitignore:
npx devdotenv init
-
Create a sample .env file:
echo "API_KEY=secret123 DATABASE_URL=postgresql://user:pass@localhost/db DEBUG=true" > .env
-
Encrypt files (sequential numbering):
npx devdotenv encrypt .env # Creates voynich-0.encrypted npx devdotenv encrypt .env.production # Creates voynich-1.encrypted npx devdotenv encrypt config.json # Creates voynich-2.encrypted
-
Decrypt files:
npx devdotenv decrypt # Auto-detects and decrypts to .env (if only one encrypted file) npx devdotenv decrypt --list # Lists all available encrypted files npx devdotenv decrypt voynich-1.encrypted .env.production # Decrypt specific file to specific output
Generate a new 256-bit encryption key and setup .gitignore.
npx devdotenv init [options]Options:
-f, --force- Overwrite existing key file-k, --key-path <path>- Path to key file (default:.devdotenv.key)
What it does:
- Creates a new encryption key
- Updates .gitignore to exclude key files and
voynich-*.encryptedfiles - Shows you what was added to .gitignore
Examples:
npx devdotenv init # Create key with default settings
npx devdotenv init --force # Overwrite existing key
npx devdotenv init -k ./keys/my.key # Custom key locationEncrypt any file to next available voynich-X.encrypted.
npx devdotenv encrypt [input-file] [options]Arguments:
input-file- File to encrypt (default:.env)
Options:
-k, --key-path <path>- Path to key file (default:.devdotenv.key)--no-obfuscation- Disable custom obfuscation layer-b, --backup- Create backup of original file
Examples:
npx devdotenv encrypt # Encrypt .env → voynich-0.encrypted
npx devdotenv encrypt .env.production # Encrypt .env.production → voynich-1.encrypted
npx devdotenv encrypt config.json # Encrypt config.json → voynich-2.encrypted
npx devdotenv encrypt -b # Create backup before encryption
npx devdotenv encrypt --no-obfuscation # Skip obfuscation layerDecrypt a specific voynich-X.encrypted file.
npx devdotenv decrypt [input-file] [output-file] [options]Arguments:
input-file- Encrypted file to decrypt (auto-detected if only one exists)output-file- Decrypted output file (default:.env)
Options:
-k, --key-path <path>- Path to key file (default:.devdotenv.key)-b, --backup- Create backup of existing output file--verify- Verify integrity without writing output--list- List all available encrypted files
Examples:
npx devdotenv decrypt # Auto-detect if only one file
npx devdotenv decrypt --list # List all encrypted files
npx devdotenv decrypt voynich-0.encrypted # Decrypt to .env
npx devdotenv decrypt voynich-1.encrypted .env.production # Decrypt to specific file
npx devdotenv decrypt voynich-2.encrypted config.json # Decrypt to config.json
npx devdotenv decrypt --verify # Verify without writing
npx devdotenv decrypt -b # Create backup of existing outputDevDotEnv uses sequential numbering for encrypted files:
- Encrypted files:
voynich-0.encrypted,voynich-1.encrypted,voynich-2.encrypted, etc. - Key file: Always
.devdotenv.key
- Simple: Easy to track multiple encrypted files
- Predictable: Always finds the next available number
- Git-friendly: Pattern
voynich-*.encryptedcovers all files - Historical: Named after the Voynich Manuscript, the most famous encrypted text in history
# Sequential encryption
.env → voynich-0.encrypted
.env.production → voynich-1.encrypted
.env.staging → voynich-2.encrypted
config.json → voynich-3.encrypted
# Targeted decryption
voynich-0.encrypted → .env
voynich-1.encrypted → .env.production
voynich-2.encrypted → .env.staging
voynich-3.encrypted → config.jsonDevDotEnv automatically manages your .gitignore to ensure security:
# DevDotEnv - never commit these files!
.devdotenv.key
.devdotenv.key.backupImportant: The encrypted files (voynich-*.encrypted) are NOT added to .gitignore because these are the files you want to commit to your repository. Only the encryption key and its backups are kept private.
- Creates .gitignore if it doesn't exist
- Appends entries if .gitignore exists but entries are missing
- Skips if entries already present
- Non-destructive - never removes existing entries
# 1. Setup (one time)
npx devdotenv init
# 2. Encrypt your secrets
npx devdotenv encrypt .env # → voynich-0.encrypted
# 3. Commit encrypted file (safe!)
git add voynich-0.encrypted .gitignore
git commit -m "Add encrypted environment variables"
# 4. Decrypt when needed
npx devdotenv decrypt # Auto-detects voynich-0.encrypted# Encrypt different environment files
npx devdotenv encrypt .env.development # → voynich-0.encrypted
git add voynich-0.encrypted && git commit -m "Add development secrets"
npx devdotenv encrypt .env.staging # → voynich-1.encrypted
git add voynich-1.encrypted && git commit -m "Add staging secrets"
npx devdotenv encrypt .env.production # → voynich-2.encrypted
git add voynich-2.encrypted && git commit -m "Add production secrets"
# List all encrypted files
npx devdotenv decrypt --list
# Decrypt specific environments
npx devdotenv decrypt voynich-0.encrypted .env.development
npx devdotenv decrypt voynich-1.encrypted .env.staging
npx devdotenv decrypt voynich-2.encrypted .env.production# Encrypt different types of files
npx devdotenv encrypt .env # → voynich-0.encrypted
npx devdotenv encrypt database.config # → voynich-1.encrypted
npx devdotenv encrypt api-keys.json # → voynich-2.encrypted
npx devdotenv encrypt secrets.yaml # → voynich-3.encrypted
# Decrypt to original formats
npx devdotenv decrypt voynich-0.encrypted .env
npx devdotenv decrypt voynich-1.encrypted database.config
npx devdotenv decrypt voynich-2.encrypted api-keys.json
npx devdotenv decrypt voynich-3.encrypted secrets.yaml- Metadata Addition: Timestamp, size, and SHA-256 checksum added to content
- Custom Obfuscation (if enabled):
- XOR obfuscation with key-derived XOR key
- Deterministic byte shuffling using Fisher-Yates algorithm
- AES-256-GCM Encryption:
- Random 12-byte IV generated for each encryption
- Authenticated encryption with 16-byte authentication tag
- File Format: Binary format with version, flags, IV, auth tag, and encrypted data
- Base64 Encoding: Final output encoded as Base64 string
- 256-bit keys generated using cryptographically secure random number generator
- Keys stored as Base64 strings in local files
- File permissions set to 600 (owner read/write only) on Unix systems
- Keys are deterministically derived for obfuscation operations
- SHA-256 checksums verify content integrity
- AES-GCM authentication tags prevent tampering
- Metadata tracking helps identify corruption or version mismatches
devdotenv/
├── bin/
│ └── cli.js # CLI entry point
├── lib/
│ ├── index.js # Main library exports
│ ├── key.js # Key generation and management
│ ├── encrypt.js # AES-256-GCM encryption
│ ├── decrypt.js # AES-256-GCM decryption
│ ├── customAlgo.js # Custom obfuscation algorithms
│ └── utils.js # File and utility functions
├── test/
│ ├── key.test.js # Key management tests
│ ├── encrypt-decrypt.test.js # Encryption/decryption tests
│ └── customAlgo.test.js # Obfuscation algorithm tests
├── package.json
├── README.md
└── .gitignore
Run the test suite:
npm test # Run all tests
npm run test:watch # Run tests in watch mode- Initialize once: Run
npx devdotenv initonce per project - Keep key secure: Never commit
.devdotenv.keyto version control - Encrypt for storage: Use
npx devdotenv encryptbefore committing - Decrypt for development: Use
npx devdotenv decryptwhen starting work - One at a time: Only one encrypted file (
voynich.encrypted) per commit
- Share keys securely: Distribute
.devdotenv.keythrough secure channels - Clear workflow: Use consistent encrypt → commit → decrypt cycle
- Verify integrity: Use
npx devdotenv decrypt --verifyto check files - Backup important files: Use
-bflag for backup creation
- Development only: Don't use for production secrets management
- Key protection: Store keys in secure, backed-up locations
- Access control: Limit access to key files and encrypted content
- Audit trail: Keep records of key rotations and file changes
Error: No encrypted files found
# Make sure you've encrypted a file first
npx devdotenv encrypt .env
# Creates voynich-0.encrypted
# Or check what files exist
npx devdotenv decrypt --listError: Multiple encrypted files found, please specify which one
# List all available encrypted files
npx devdotenv decrypt --list
# Then decrypt the specific file you want
npx devdotenv decrypt voynich-1.encrypted .env.productionError: Encrypted file not found: voynich-X.encrypted
# Check what encrypted files exist
npx devdotenv decrypt --list
# Use the correct filename
npx devdotenv decrypt voynich-0.encryptedError: Key file not found
npx devdotenv init # Generate a new keyError: Decryption failed: invalid key or corrupted data
- Check if you're using the correct key file
- Verify the encrypted file hasn't been corrupted
- Ensure file was encrypted with the same key
MIT License - see LICENSE file for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make changes and add tests
- Run tests:
npm test - Commit changes:
git commit -am 'Add feature' - Push to branch:
git push origin feature-name - Submit a pull request
- Issues: Report bugs and request features on GitHub Issues
- Documentation: Check this README for usage information
- Security: Report security issues responsibly through private channels
WARNING: This tool is for development use only. For production secrets management, use dedicated solutions like HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, or similar enterprise-grade systems.