14 KiB
Vendored
Protected Notes and Encryption System
Trilium's Protected Notes system provides robust, selective encryption for sensitive content using industry-standard AES encryption with scrypt-based key derivation. This guide covers setup, usage, and security considerations.
Architecture Overview
Encryption Stack
- Cipher: AES-128-CBC (Advanced Encryption Standard, Cipher Block Chaining mode)
- Key Derivation: Scrypt (N=16384, r=8, p=1) with random salt
- Integrity Protection: SHA-1 digest verification
- Encoding: Base64 for storage and transmission
Key Hierarchy
Master Password (User Input)
↓
Password-Derived Key (Scrypt + Salt)
↓
Encrypted Data Key (AES-128-CBC)
↓
Session Data Key (In Memory)
↓
Protected Content (AES-128-CBC)
Setting Up Protected Notes
Initial Configuration
-
Set Master Password
- Access via Options → Security → Password
- Minimum 8 characters (recommend 12+)
- Use unique, complex password
-
Configure Session Settings
- Session timeout (default: 10 minutes)
- Auto-logout on inactivity
- Multi-client session handling
-
Security Options
- Password strength requirements
- Session notification preferences
- Audit logging settings
Creating Protected Notes
Method 1: Right-Click Menu
- Right-click any note in the tree
- Select "Toggle Protected Status"
- Confirm protection in dialog
Method 2: Note Actions Menu
- Open note editor
- Click Actions button (⚙️)
- Select "Protect this note"
Method 3: Keyboard Shortcut
- Select note
- Press
Ctrl+Shift+U(toggle protection)
Bulk Protection
Protect multiple notes simultaneously:
-
Subtree Protection
- Right-click parent note
- Select "Protect subtree"
- All child notes become protected
-
Batch Selection
- Use Ctrl+click to select multiple notes
- Right-click → "Protect selected notes"
Protected Sessions
Session Lifecycle
Entering Protected Session
Method 1: Manual Entry
1. Click shield icon in toolbar
2. Enter master password
3. Session activates (shield turns green)
Method 2: Automatic Prompt
1. Access protected note
2. Password dialog appears
3. Enter credentials to continue
Method 3: Keyboard Shortcut
Press Ctrl+Shift+P to enter protected session
Session Management
- Active Session: Shield icon green, protected content accessible
- Session Timeout: Configurable (60-3600 seconds)
- Activity Tracking: Timeout resets with each protected note access
- Multi-Client: Independent sessions per browser/client
Leaving Protected Session
Manual Logout:
- Click green shield icon
- Select "Leave protected session"
Automatic Logout:
- Inactivity timeout
- Browser/application close
- Security state changes
Session Security Features
Timeout Configuration
// Access via Options → Protected Session
protectedSessionTimeout: number // seconds (default: 600)
protectedSessionWarning: boolean // show timeout warnings
Security Events
- Session entry/exit logged
- Failed authentication attempts tracked
- Unusual access patterns detected
- Audit trail maintained
Encryption Technical Details
Encryption Process Flow
Plaintext Data
↓
1. Compute SHA-1 digest (integrity check)
↓
2. Prepend digest (4 bytes) to plaintext
↓
3. Generate random IV (16 bytes)
↓
4. Encrypt with AES-128-CBC (data key + IV)
↓
5. Prepend IV to encrypted data
↓
6. Encode as Base64
↓
Stored Ciphertext
Decryption Process Flow
Base64 Ciphertext
↓
1. Decode from Base64
↓
2. Extract IV (first 16 bytes)
↓
3. Extract encrypted data (remaining bytes)
↓
4. Decrypt with AES-128-CBC (data key + IV)
↓
5. Extract digest (first 4 bytes) and plaintext
↓
6. Verify digest matches computed SHA-1
↓
Verified Plaintext Data
Key Derivation Details
Scrypt Parameters
const scryptParams = {
N: 16384, // CPU/memory cost (2^14)
r: 8, // Block size parameter
p: 1, // Parallelization parameter
dkLen: 32 // Derived key length (bytes)
};
Salt Generation
- Password Salt: 32-byte random salt for password verification
- Data Key Salt: 32-byte random salt for data key encryption
- Cryptographic Quality: Node.js crypto.randomBytes()
Key Storage
-- Options table entries
INSERT INTO options VALUES
('passwordVerificationSalt', '<32-byte-salt>'),
('passwordDerivedKeySalt', '<32-byte-salt>'),
('passwordVerificationHash', '<scrypt-hash>'),
('encryptedDataKey', '<encrypted-key>');
Security Considerations
Threat Model
Protected Against
✅ Database Theft: Encrypted content unreadable without password ✅ Backup Compromise: Encrypted backups maintain protection ✅ Network Interception: Data encrypted at rest and in transit ✅ Server Breach: Server never stores plaintext of protected content ✅ Physical Storage Access: Database files encrypted
Not Protected Against
❌ Keyloggers: Malware capturing password input ❌ Memory Dumps: Active sessions store keys in memory ❌ Screen Capture: Displayed content vulnerable ❌ Social Engineering: User convinced to reveal password ❌ Endpoint Compromise: Malware on user device
Security Limitations
Metadata Exposure
- Note Structure: Tree hierarchy visible
- Timestamps: Creation/modification dates unencrypted
- Note IDs: Internal identifiers exposed
- Attributes: Some metadata may be unencrypted
Search Limitations
- Full-text Search: Protected content excluded from search index
- Cross-references: Links to protected notes may be limited
- Content Analysis: Automated analysis features disabled
Best Practices
Password Management
-
Strong Passwords
- Minimum 12 characters
- Mix of letters, numbers, symbols
- Avoid common patterns
-
Password Storage
- Use reputable password manager
- Store recovery information securely
- Don't reuse passwords
-
Regular Updates
- Change password periodically
- Update after suspected compromise
- Coordinate with team members
Session Management
-
Timeout Configuration
- Set appropriate timeout for usage pattern
- Shorter timeouts for sensitive environments
- Balance security with usability
-
Access Control
- Lock workstation when away
- Use screen savers with password
- Log out of shared computers
-
Multi-Device Usage
- Use consistent passwords across devices
- Monitor active sessions
- Revoke compromised device access
Troubleshooting
Common Issues
Decryption Failures
Error: "Could not decrypt string"
Causes:
- Incorrect password
- Corrupted encrypted data
- Database schema issues
- Memory corruption
Solutions:
# Check database integrity
sqlite3 document.db "PRAGMA integrity_check;"
# Verify options table
sqlite3 document.db "SELECT name, length(value) FROM options WHERE name LIKE 'password%';"
# Test password verification
# (In protected session troubleshooting)
Session Problems
Error: Protected session won't start
Diagnostic Steps:
- Check browser console for JavaScript errors
- Verify network connectivity
- Review server logs for authentication errors
- Test with fresh browser session
Solutions:
# Clear browser data
# Restart Trilium server
# Check file permissions on database
# Verify encryption keys in options table
Performance Issues
Symptoms: Slow password verification, high CPU usage
Optimization:
// Advanced users only - modify scrypt parameters
const optimizedParams = {
N: 8192, // Reduce for faster verification
r: 8, // Keep default
p: 1 // Keep default
};
Hardware Recommendations:
- Minimum 4GB RAM for scrypt operations
- Modern CPU with AES-NI support
- SSD storage for database files
Recovery Procedures
Forgotten Password
No Built-in Recovery: Trilium cannot recover forgotten passwords
Options:
- Restore from Backup: Use backup with known password
- Partial Recovery: Export unprotected content
- Complete Reset: Lose all protected content
# Reset password (loses all protected content)
sqlite3 document.db "
UPDATE options SET value = '' WHERE name IN (
'passwordVerificationSalt',
'passwordDerivedKeySalt',
'passwordVerificationHash',
'encryptedDataKey'
);
"
Data Corruption
Corruption Detection:
- Decryption failures
- Database integrity errors
- Inconsistent note content
Recovery Steps:
- Stop Trilium application
- Create backup of current database
- Run database integrity check
- Restore from known good backup
- Compare and merge changes if needed
# Database integrity check
sqlite3 document.db "PRAGMA integrity_check;"
# Quick corruption check
sqlite3 document.db "SELECT COUNT(*) FROM notes WHERE isProtected = 1;"
Performance Optimization
System Requirements
Minimum Requirements
- CPU: 1GHz processor with AES support
- RAM: 2GB available memory
- Storage: 100MB free disk space
- Network: Stable connection for sync
Recommended Configuration
- CPU: Multi-core processor with AES-NI
- RAM: 8GB+ for large datasets
- Storage: SSD for database files
- Network: Broadband for sync operations
Performance Tuning
Database Optimization
-- Optimize database performance
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = 10000;
PRAGMA temp_store = MEMORY;
Memory Management
- Session Caching: Keep frequently accessed protected notes in memory
- Garbage Collection: Clear old session data regularly
- Resource Monitoring: Monitor memory usage patterns
Network Optimization
- Compression: Enable content compression
- Caching: Use appropriate cache headers
- Connection Pooling: Optimize database connections
Compliance and Auditing
Encryption Standards
Algorithm Compliance
- AES-128: NIST approved, FIPS 140-2 Level 1
- Scrypt: RFC 7914 standard
- SHA-1: NIST standard (integrity only)
Key Management
- Generation: Cryptographically secure random number generator
- Storage: Encrypted at rest
- Transmission: Never transmitted in plaintext
- Destruction: Securely cleared from memory
Audit Requirements
Logging Events
// Security events logged
enum AuditEvents {
PROTECTED_SESSION_START = 'protected_session_start',
PROTECTED_SESSION_END = 'protected_session_end',
PROTECTED_NOTE_ACCESS = 'protected_note_access',
ENCRYPTION_FAILURE = 'encryption_failure',
DECRYPTION_FAILURE = 'decryption_failure',
PASSWORD_CHANGE = 'password_change'
}
Compliance Reports
- Authentication success/failure rates
- Protected content access patterns
- Security event timelines
- Performance metrics
Regulatory Considerations
GDPR Compliance
- Data Protection: AES encryption provides technical safeguards
- Right to Erasure: Secure deletion of encryption keys
- Data Portability: Export capabilities for protected content
- Privacy by Design: Encryption built into architecture
HIPAA Requirements
- Administrative Safeguards: Access controls and audit trails
- Physical Safeguards: Workstation security recommendations
- Technical Safeguards: AES encryption meets requirements
Industry Standards
- ISO 27001: Information security management
- SOC 2: Security and availability controls
- PCI DSS: Data protection requirements
Advanced Configuration
Custom Encryption Parameters
Warning: Modifying encryption parameters requires expert knowledge and may break compatibility with future versions.
// File: apps/server/src/services/encryption/my_scrypt.ts
const customScryptParams = {
N: 32768, // Higher security (slower)
r: 8, // Block size
p: 2 // Parallel processing
};
Integration Examples
Backend Script Access
// Accessing protected notes in backend scripts
const protectedNote = api.getNote(noteId);
if (protectedNote.isProtected) {
// Content is encrypted unless in protected session
if (api.isProtectedSessionAvailable()) {
const content = protectedNote.getContent();
// Process decrypted content
} else {
// Request protected session
throw new Error('Protected session required');
}
}
API Integration
// External API access to protected content
const etapiToken = 'your-etapi-token';
const headers = {
'Authorization': `Bearer ${etapiToken}`,
'Content-Type': 'application/json'
};
// Note: ETAPI cannot access protected content
// Protected session must be established in web interface
Backup and Migration
Backup Strategies
Complete Database Backup
# Stop Trilium first
sqlite3 document.db ".backup backup-$(date +%Y%m%d).db"
# Compressed backup
tar czf trilium-backup-$(date +%Y%m%d).tar.gz \
document.db session_secret.txt config.ini
Encrypted Backup
# GPG encrypted backup
tar czf - trilium-data/ | \
gpg --cipher-algo AES256 --compress-algo 1 --symmetric \
--output trilium-backup-$(date +%Y%m%d).tar.gz.gpg
Protected Content Export
// Export during protected session
const protectedNotes = api.getNotesByLabel('#protected');
protectedNotes.forEach(note => {
if (note.isProtected) {
const exportData = {
title: note.title,
content: note.getContent(),
attributes: note.getAttributes()
};
// Save to secure location
}
});
Migration Procedures
Same-Password Migration
- Export data from source installation
- Create fresh installation
- Set same master password
- Import exported data
- Verify protected content access
Password Change Migration
- Enter protected session in source
- Export all protected content unencrypted
- Create new installation with new password
- Import content (will be re-encrypted)
- Verify all content accessible
Cross-Platform Migration
# Export from source platform
trilium-server --export=/path/to/export.zip
# Import to target platform
trilium-server --import=/path/to/export.zip
Remember: The security of your protected notes depends on maintaining good password practices and following security best practices for your overall system environment.