A functional end-to-end encrypted file storage system. Files are encrypted on the client with AES-256-GCM before being sent to the server. The server never sees unencrypted data.
- End-to-End Encryption: Files encrypted with AES-256-GCM on the client side
- Zero-Knowledge Storage: Server stores only encrypted blobs; cannot decrypt files
- RSA-4096 Key Pairs: Each user gets a unique key pair for file sharing
- Password Hashing: Bcrypt (10 rounds) + PBKDF2 (100k iterations) for key derivation
- Client-Side Encryption: All encryption/decryption happens in the browser
- Audit Logging: All file operations tracked (who, what, when, why)
├── backend/
│ ├── src/
│ │ ├── config/
│ │ │ ├── database.js # PostgreSQL connection
│ │ │ └── sql.sql # Database schema
│ │ ├── middleware/
│ │ │ └── auth.js # JWT authentication middleware
│ │ ├── models/
│ │ │ └── user.js # Database models
│ │ ├── routes/
│ │ │ ├── auth.js # Authentication endpoints
│ │ │ └── files.js # File management endpoints
│ │ ├── utils/
│ │ │ ├── encryption.js # AES-256-GCM, RSA encryption
│ │ │ └── auth.js # JWT, password hashing
│ │ └── index.js # Express server entry point
│ ├── uploads/ # Encrypted file storage (local)
│ ├── package.json
│ ├── .env # Environment variables
│ └── .gitignore
│
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── Notification.js # Toast notifications
│ │ │ ├── PasswordInput.js # Password input with strength meter
│ │ │ ├── Modal.js # Modal and confirmation dialogs
│ │ │ ├── FileUploader.js # Drag-and-drop file upload
│ │ │ └── FileList.js # File list with actions
│ │ ├── pages/
│ │ │ ├── LoginPage.js # Login/signup page
│ │ │ └── DashboardPage.js # Main dashboard
│ │ ├── context/
│ │ │ ├── AuthContext.js # Auth state management
│ │ │ └── NotificationContext.js # Notification state
│ │ ├── utils/
│ │ │ ├── api.js # API client
│ │ │ └── encryption.js # Client-side encryption
│ │ ├── App.js # Main app component
│ │ ├── index.js # React entry point
│ │ └── index.css # Global styles
│ ├── public/
│ │ └── index.html # HTML template
│ ├── package.json
│ ├── .env # Environment variables
│ ├── tailwind.config.js # Tailwind CSS config
│ ├── postcss.config.js # PostCSS config
│ └── .gitignore
│
└── README.md
- Node.js (v14 or higher)
- PostgreSQL (v12 or higher)
- npm or yarn
-
Install dependencies:
cd backend npm install -
Set up PostgreSQL database:
createdb secure_file_storage psql -U postgres -d secure_file_storage -f src/config/sql.sql
-
Configure environment (.env):
NODE_ENV=development PORT=5000 DB_HOST=localhost DB_PORT=5432 DB_NAME=secure_file_storage DB_USER=postgres DB_PASSWORD=your_password JWT_SECRET=your-super-secret-jwt-key JWT_EXPIRE=24h RSA_KEY_SIZE=4096 UPLOAD_DIR=./uploads MAX_FILE_SIZE=104857600 -
Start backend server:
npm run dev
Server runs on http://localhost:5000
-
Install dependencies:
cd frontend npm install -
Configure environment (.env):
REACT_APP_API_URL=http://localhost:5000/api -
Start development server:
npm start
App runs on http://localhost:3000
-
POST /api/auth/signup- Create account, generate RSA keypair- Request:
{ email, password } - Response:
{ token, user }
- Request:
-
POST /api/auth/login- Login, decrypt stored private key- Request:
{ email, password } - Response:
{ token, user }
- Request:
-
GET /api/auth/me- Get current user (JWT required)- Response:
{ id, email, publicKey }
- Response:
-
POST /api/files/upload- Upload encrypted file- Request: FormData with file + encryptedKey
- Response:
{ fileId, filename, hash, size }
-
GET /api/files/list- List user's files- Response:
{ ownFiles, sharedFiles, stats }
- Response:
-
GET /api/files/download/:fileId- Download encrypted file- Response:
{ fileId, filename, encryptedData, encryptedKey }
- Response:
-
DELETE /api/files/delete/:fileId- Delete file from server- Response:
{ success }
- Response:
-
POST /api/files/share- Share file with another user- Request:
{ fileId, recipientEmail, encryptedKey } - Response:
{ shareId }
- Request:
- User picks file in browser
- Generate random 256-bit AES key + 96-bit IV
- Encrypt file with AES-256-GCM (authenticated)
- Encrypt AES key with user's RSA public key
- Send encrypted file + encrypted key to server
- Server stores as opaque blob (can't decrypt)
- User deletes original from disk
- User requests file from server
- Server returns encrypted file + encrypted key
- Browser decrypts AES key using user's RSA private key
- Browser decrypts file using AES key
- File appears to user decrypted
- File owner has AES key (encrypted with their key)
- Owner re-encrypts AES key with recipient's RSA public key
- Owner sends encrypted key to recipient
- Recipient decrypts key using their private key
- Recipient can now decrypt the shared file
id(UUID) - Primary keyemail(VARCHAR) - Unique emailencrypted_private_key(TEXT) - Password-protected private keypublic_key(TEXT) - RSA public keypassword_hash(VARCHAR) - Bcrypt hashpassword_salt(VARCHAR) - PBKDF2 saltcreated_at(TIMESTAMP)
id(UUID) - Primary keyowner_id(UUID) - FK to usersfilename(VARCHAR) - Original filenamefile_hash(VARCHAR) - SHA-256 hashencrypted_key(TEXT) - Encrypted AES keyfile_path(VARCHAR) - Local storage pathsize(BIGINT) - File size in bytescreated_at(TIMESTAMP)
id(UUID) - Primary keyfile_id(UUID) - FK to filesowner_id(UUID) - FK to usersrecipient_id(UUID) - FK to usersencrypted_key(TEXT) - Key encrypted with recipient's public keycreated_at(TIMESTAMP)
id(UUID) - Primary keyuser_id(UUID) - FK to usersaction(VARCHAR) - Action typeresource_type(VARCHAR) - Resource being acted onresource_id(UUID) - Resource IDdetails(JSONB) - Additional detailsip_address(VARCHAR) - IP address of requestcreated_at(TIMESTAMP)
- AES-256-GCM authenticated encryption
- RSA-4096 asymmetric encryption for key sharing
- Bcrypt password hashing with salt
- PBKDF2 key derivation (100,000 iterations)
- JWT token-based authentication
- CORS protection
- Audit logging
- Client-side encryption (zero-knowledge)
- Two-Factor Authentication (TOTP/WebAuthn)
- Rate limiting on login attempts
- Password reset via email with secure tokens
- Biometric unlock (fingerprint/FaceID)
- File versioning
- Trash/recover deleted files
- End-to-end encrypted sharing links
- Public key backup/recovery
- Encrypted file sync across devices
- Clean, modern design with Tailwind CSS
- Responsive layout (mobile, tablet, desktop)
- Drag-and-drop file upload
- Upload progress bar
- Real-time password strength meter
- Toast notifications for user feedback
- Modal dialogs for confirmations
- File search and filtering
- Storage statistics dashboard
- Settings page for account management
- Files stored encrypted on server (no decryption overhead)
- Client-side encryption for instant responsiveness
- Efficient file chunking for large files
- Database indexing for fast queries
- CORS and caching headers optimized
-
Database connection error:
- Ensure PostgreSQL is running
- Check
.envdatabase credentials - Run schema migration:
psql -U postgres -d secure_file_storage -f src/config/sql.sql
-
Port already in use:
- Change PORT in
.envor kill existing process
- Change PORT in
-
CORS errors:
- Ensure frontend URL is in CORS whitelist in
backend/src/index.js
- Ensure frontend URL is in CORS whitelist in
-
API connection error:
- Ensure backend is running on correct port
- Check
REACT_APP_API_URLin.env - Clear browser cache and restart dev server
-
Encryption errors:
- Check browser console for WebCrypto API support
- Ensure HTTPS is used in production
curl -X POST http://localhost:5000/api/auth/signup \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"SecurePassword123!"}'curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"SecurePassword123!"}'curl -X POST http://localhost:5000/api/files/upload \
-H "Authorization: Bearer <token>" \
-F "file=@document.pdf" \
-F "encryptedKey=<base64-encrypted-key>"-
Environment:
- Change JWT_SECRET to secure random value
- Set NODE_ENV=production
- Use environment variables for sensitive data
- Set up SSL/TLS certificates
-
Database:
- Use managed PostgreSQL service (AWS RDS, Azure Database)
- Enable backups and replication
- Use strong database passwords
-
File Storage:
- Use S3 or similar cloud storage for production
- Implement versioning
- Set up lifecycle policies for old files
-
Frontend:
- Build and serve static files
- Enable gzip compression
- Set up CDN
- Implement service workers for offline support
-
Monitoring:
- Set up error tracking (Sentry)
- Monitor database performance
- Log file access and modifications
- Set up alerting for security events
MIT License - Feel free to use for personal and commercial projects
Contributions welcome! Please submit pull requests with improvements.
For issues and questions, please open a GitHub issue.
Built for secure file storage