A CLI tool for securely encrypting and decrypting .env files using AES-256-GCM
npm install devdotenv.env files using AES-256-GCM encryption with optional custom obfuscation.
voynich.encrypted
bash
No installation needed! Use directly with npx
npx devdotenv init
npx devdotenv encrypt .env
npx devdotenv decrypt
`
$3
`bash
npm install devdotenv
npx devdotenv init
`
$3
`bash
git clone https://github.com/guinat/devdotenv-node.git
cd devdotenv-node
npm install
npm link # Makes 'devdotenv' command available globally
`
Quick Start
1. Initialize encryption key and setup .gitignore:
`bash
npx devdotenv init
`
2. Create a sample .env file:
`bash
echo "API_KEY=secret123
DATABASE_URL=postgresql://user:pass@localhost/db
DEBUG=true" > .env
`
3. Encrypt files (sequential numbering):
`bash
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
`
4. Decrypt files:
`bash
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
`
CLI Commands
$3
Generate a new 256-bit encryption key and setup .gitignore.
`bash
npx devdotenv init [options]
`
Options:
- -f, --force - Overwrite existing key file
- -k, --key-path - Path to key file (default: .devdotenv.key)
What it does:
- Creates a new encryption key
- Updates .gitignore to exclude key files and voynich-*.encrypted files
- Shows you what was added to .gitignore
Examples:
`bash
npx devdotenv init # Create key with default settings
npx devdotenv init --force # Overwrite existing key
npx devdotenv init -k ./keys/my.key # Custom key location
`
$3
Encrypt any file to next available voynich-X.encrypted.
`bash
npx devdotenv encrypt [input-file] [options]
`
Arguments:
- input-file - File to encrypt (default: .env)
Options:
- -k, --key-path - Path to key file (default: .devdotenv.key)
- --no-obfuscation - Disable custom obfuscation layer
- -b, --backup - Create backup of original file
Examples:
`bash
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 layer
`
$3
Decrypt a specific voynich-X.encrypted file.
`bash
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 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:
`bash
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 output
`
File Strategy
DevDotEnv uses sequential numbering for encrypted files:
$3
- Encrypted files: voynich-0.encrypted, voynich-1.encrypted, voynich-2.encrypted, etc.
- Key file: Always .devdotenv.key
$3
- Simple: Easy to track multiple encrypted files
- Predictable: Always finds the next available number
- Git-friendly: Pattern voynich-*.encrypted covers all files
- Historical: Named after the Voynich Manuscript, the most famous encrypted text in history
$3
`bash
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.json
`
.gitignore Management
DevDotEnv automatically manages your .gitignore to ensure security:
$3
`gitignore
DevDotEnv - never commit these files!
.devdotenv.key
.devdotenv.key.backup
`
Important: 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.
$3
- 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
Usage Examples
$3
`bash
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
`
$3
`bash
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
`
$3
`bash
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
`
Security Implementation
$3
1. Metadata Addition: Timestamp, size, and SHA-256 checksum added to content
2. Custom Obfuscation (if enabled):
- XOR obfuscation with key-derived XOR key
- Deterministic byte shuffling using Fisher-Yates algorithm
3. AES-256-GCM Encryption:
- Random 12-byte IV generated for each encryption
- Authenticated encryption with 16-byte authentication tag
4. File Format: Binary format with version, flags, IV, auth tag, and encrypted data
5. Base64 Encoding: Final output encoded as Base64 string
$3
- 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
$3
- SHA-256 checksums verify content integrity
- AES-GCM authentication tags prevent tampering
- Metadata tracking helps identify corruption or version mismatches
Project Structure
`
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
`
Testing
Run the test suite:
`bash
npm test # Run all tests
npm run test:watch # Run tests in watch mode
`
Best Practices
$3
1. Initialize once: Run npx devdotenv init once per project
2. Keep key secure: Never commit .devdotenv.key to version control
3. Encrypt for storage: Use npx devdotenv encrypt before committing
4. Decrypt for development: Use npx devdotenv decrypt when starting work
5. One at a time: Only one encrypted file (voynich.encrypted) per commit
$3
1. Share keys securely: Distribute .devdotenv.key through secure channels
2. Clear workflow: Use consistent encrypt → commit → decrypt cycle
3. Verify integrity: Use npx devdotenv decrypt --verify to check files
4. Backup important files: Use -b flag for backup creation
$3
- 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
Troubleshooting
$3
Error: No encrypted files found
`bash
Make sure you've encrypted a file first
npx devdotenv encrypt .env
Creates voynich-0.encrypted
Or check what files exist
npx devdotenv decrypt --list
`
Error: Multiple encrypted files found, please specify which one
`bash
List all available encrypted files
npx devdotenv decrypt --list
Then decrypt the specific file you want
npx devdotenv decrypt voynich-1.encrypted .env.production
`
Error: Encrypted file not found: voynich-X.encrypted
`bash
Check what encrypted files exist
npx devdotenv decrypt --list
Use the correct filename
npx devdotenv decrypt voynich-0.encrypted
`
Error: Key file not found
`bash
npx devdotenv init # Generate a new key
`
Error: 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
License
MIT License - see LICENSE file for details.
Contributing
1. Fork the repository
2. Create a feature branch: git checkout -b feature-name
3. Make changes and add tests
4. Run tests: npm test
5. Commit changes: git commit -am 'Add feature'
6. Push to branch: git push origin feature-name`