Next PGP is an elegant, powerful, and modern Progressive Web App (PWA) built with Next.js. It provides an app like experience for generating keys, managing keyrings, and securely encrypting and decrypting messages with ease.
- Key Generation:
- Effortlessly generate secure PGP keys
- Supports multiple algorithms, including:
- Curve25519 (EdDSA/ECDH) - Recommended
- NIST P-256, P-521 (ECDSA/ECDH)
- Brainpool P-256r1, P-512r1 (ECDSA/ECDH)
- RSA 2048, 3072, 4096
- Keyring Management:
- Add, manage, delete, import, export, and backup keys
- Search, import, and publish public keys via PGP keyservers
- Add, change, and remove passphrases
- Add, manage, and revoke User IDs
- Add, manage, and revoke subkeys
- Encryption & Decryption:
- Encrypt and decrypt messages with ease
- Secure file encryption and decryption
- Intuitive user interface for seamless operation
- Batch File Encryption & Decryption:
- Encrypt multiple files at once
- Decrypt multiple files efficiently
- Folder Encryption & Decryption:
- Encrypt and decrypt entire folders recursively
- Maintain original directory structure
- Cloud Management:
- Securely backup PGP keys to the cloud
- Manage keys remotely with encrypted vaults
- Ensure top-tier protection with end-to-end encryption
- Encrypted Vaults:
- Password-derived key security using PBKDF2 (1,000,000 iterations, SHA-512)
- Vault data including verification cipher encrypted client-side
- Strong confidentiality and integrity with AES-256-GCM
- Web Worker Multithreading:
- Dynamically scales encryption and decryption workloads in parallel across all CPU cores
- Keeps the interface fast and responsive, even during heavy processing
- Automatically adapts to your device's performance capabilities
- Secure Local Storage: Utilizes IndexedDB to store keys locally, encrypted by the Web Crypto API.
- Modern UI: Clean and elegant user experience built on modern design principles.
- Blazing Fast Performance: Built with Next.js to deliver superior speed and performance.
- Smooth Cloud Management: Seamless and secure integration of cloud based key storage and retrieval for enhanced accessibility and control.
- Cross Platform Progressive Web App (PWA): Web based application that works on every device β Windows, macOS, Linux, Android, and iOS with offline capabilities.
- Framework: Next JS
- UI Components: Hero UI
- Database: MongoDB for cloud storage and user vault management.
- PWA Integration: Service workers, manifest setup, and offline support.
- State Management: Efficient handling of state for keyrings and messages.
- Performance Optimization: Dynamic Web Worker pool for parallel cryptographic operations using all available CPU cores
Next PGP is built around a Zero-Knowledge and End-to-End Encryption (E2EE) model β ensuring that your secrets stay yours, even in the cloud.
- True End-to-End Encryption (E2EE): All encryption and decryption happens entirely on the client-side. Your PGP keys, vault contents, and sensitive data are encrypted before ever leaving your device β the server never sees them unencrypted.
- Vault Protection: Your vault password is used to derive an encryption key via PBKDF2 (with 1,000,000 iterations) on the client, securing your data with AES-256-GCM. For authentication, the password verification is also handled client-side ensuring zero-knowledge architecture at every layer.
- Zero-knowledge cloud storage: Although you can back up and sync your encrypted vault to the cloud, it is fully opaque to the server. Only you can decrypt it.
- In-memory vault context: Vault password is never stored in session or local storage β it's kept in memory only while the app is open, adding an additional layer of runtime safety.
- Built on HTTPS + Web Crypto API: Communication is always encrypted in transit, and cryptographic operations use trusted, native browser APIs.
ββ User sets app password
ββ Generate 16-byte random salt
ββ Derive 32-byte key from password + salt using PBKDF2-SHA256 (1,000,000 iterations)
ββ Get or generate main encryption key (AES-GCM 256-bit)
ββ Export main crypto key to raw bytes
ββ Encrypt main crypto key with password-derived key:
β ββ Generate 12-byte random IV
β ββ Encrypt main crypto key bytes with AES-GCM + IV
β ββ Store encrypted main crypto key + IV + salt + password hash
ββ Generate password hash for verification (SHA-256)
ββ Store in IndexedDB:
β ββ encrypted: encrypted main crypto key bytes
β ββ iv: 12-byte IV
β ββ salt: 16-byte salt
β ββ passwordHash: SHA-256 hash of password
β ββ isPasswordProtected: true
ββ Store decrypted main crypto key in memory (encrypted with temporary key)
ββ User enters app password
ββ Fetch encrypted main crypto key record from IndexedDB
ββ Validate password protection is enabled
ββ Derive 32-byte key from password + stored salt using PBKDF2-SHA256 (1M iterations)
ββ Decrypt main crypto key:
β ββ Use derived key + stored IV
β ββ Decrypt encrypted main crypto key bytes with AES-GCM
β ββ Import decrypted bytes as AES-GCM key
ββ Verify password by checking if decryption succeeds
β ββ If successful β correct password β unlock app
β ββ If fails β incorrect password β show error
ββ Store decrypted main crypto key in memory:
β ββ Generate temporary AES-GCM key
β ββ Encrypt decrypted main crypto key with temporary key
β ββ Store encrypted main crypto key + IV + temp key in memory
β ββ Set session flag in sessionStorage
ββ App is now unlocked and can access PGP keys
ββ User removes password protection
ββ Verify current password (requires decrypted main crypto key in memory)
ββ Generate new unencrypted main crypto key (AES-GCM 256-bit)
ββ Re-encrypt all PGP keys:
β ββ Decrypt each PGP key with old main crypto key
β ββ Re-encrypt with new main crypto key + random IV
β ββ Update IndexedDB with new encrypted data
ββ Store new unencrypted main crypto key in IndexedDB:
β ββ key: raw main crypto key bytes
β ββ isPasswordProtected: false
ββ Clear password protection completely
ββ Temporary session validation
ββ Auto-clear on page refresh
ββ Generate temporary AES-GCM key for memory storage
ββ Re-encrypt decrypted main crypto key with temporary key
ββ Store in memory (encrypted)
ββ No persistent sessions
ββ PGP keys encrypted with AES-GCM + random IV
ββ IndexedDB encryption with main crypto key
ββ Zero-knowledge architecture (client-side only)
ββ Web Crypto API for all operations
ββ HTTPS enforcement
ββ AES-GCM encryption for data protection
ββ PBKDF2 key derivation for password protection
ββ User enters password
ββ Generate 32-byte random verification text (Uint8Array)
ββ Convert to hex string and add "VERIFY:" prefix
ββ Encrypt verification text with password:
β ββ Generate 16-byte random salt
β ββ Generate 12-byte random IV
β ββ Derive 64-byte key from password + salt using PBKDF2-SHA512 (1,000,000 iterations)
β β ββ First 32 bytes: AES-GCM key
β β ββ Next 32 bytes: HMAC-SHA256 key
β ββ Compress plaintext using DEFLATE (pako)
β ββ Encrypt compressed data with AES-GCM
β ββ Construct 45-byte header:
β β ββ 2 bytes: MAGIC ('NP')
β β ββ 1 byte: ENCRYPTION_VERSION
β β ββ 1 byte: PURPOSE
β β ββ 1 byte: KDF_ID (0x01 = PBKDF2)
β β ββ 1 byte: CIPHER_ID (0x01 = AES-GCM)
β β ββ 1 byte: FLAGS (0x01 = compression enabled)
β β ββ 4 bytes: ITERATIONS (big-endian uint32)
β β ββ 2 bytes: RESERVED (0x0000)
β β ββ 32 bytes: SHA-256 hash of header prefix (integrity)
β ββ Generate HMAC-SHA256 of (header + ciphertext + IV + salt)
β ββ Concatenate:
β β ββ header (45 bytes)
β β ββ ciphertext
β β ββ IV (12 bytes)
β β ββ salt (16 bytes)
β β ββ HMAC (32 bytes)
β ββ Base64 encode full payload β `verificationCipher`
ββ Send `verificationCipher` to server (password never sent)
ββ User enters password
ββ Fetch base64 `verificationCipher` from server
ββ Decode and parse:
β ββ header (45 bytes)
β ββ ciphertext
β ββ IV (12 bytes)
β ββ salt (16 bytes)
β ββ HMAC (32 bytes)
ββ Validate:
β ββ MAGIC bytes == "NP"
β ββ VERSION supported
β ββ HEADER hash matches
β ββ HMAC signature valid
ββ Derive key using KDF_ID (PBKDF2-SHA512 with salt + iterations)
β ββ Split into AES-GCM key + HMAC key
ββ Decrypt ciphertext with AES-GCM using IV
ββ Decompress decrypted data using DEFLATE (pako)
ββ Check if plaintext starts with "VERIFY:"
β ββ If yes β correct password β unlock vault
β ββ Else β incorrect password β show error
ββ Call VaultContext.unlockVault(password)
β ββ Get masterKey from IndexedDB
β ββ Encrypt vault password with AES-GCM + random IV using masterKey
β ββ Store encrypted password + IV in memory (React state)
β ββ Mark vault as unlocked
ββ Call server API `/api/vault/unlock`
ββ Server issues a secure jwt vault session token cookie (30 min expiry)
ββ Vault password stored encrypted in memory (React state)
ββ Encryption uses separate masterKey (from IndexedDB)
ββ Password decrypted on-demand via VaultContext.getVaultPassword()
ββ Retrieve vault password by calling VaultContext.getVaultPassword()
ββ For each PGP key to backup:
ββ Compute hashes and compare with:
β ββ IndexedDB PGP key
β ββ MongoDB PGP key
β ββ To check the PGP key is already backed up to the MongoDB or not
ββ If not already backed up:
β ββ Generate 16-byte random salt
β ββ Generate 12-byte random IV
β ββ Compress the PGP key with DEFLATE (pako)
β ββ Derive 64-byte key from vault password + salt using PBKDF2-SHA512 (1M iterations)
β β ββ First 32 bytes: AES-GCM key
β β ββ Next 32 bytes: HMAC-SHA256 key
β ββ Encrypt compressed PGP key with AES-GCM + IV
β ββ Build 45-byte header:
β β ββ 2B MAGIC ('NP')
β β ββ 1B VERSION
β β ββ 1B PURPOSE
β β ββ 1B KDF_ID (0x01)
β β ββ 1B CIPHER_ID (0x01)
β β ββ 1B FLAGS (0x01 = compressed)
β β ββ 4B ITERATIONS
β β ββ 2B RESERVED
β β ββ 32B SHA-256(header)
β ββ Compute HMAC-SHA256 over (header + ciphertext + IV + salt)
β ββ Concatenate: headerββ+ ciphertextββ+ IVββ+ saltββ+ HMAC
β ββ Base64 encode β encrypted PGP key
ββ Send the encrypted PGP key and its hash to the server and store in the database
ββ Retrieve vault password by calling VaultContext.getVaultPassword()
ββ Retrieve list of encrypted PGP keys from MongoDB
ββ For each encrypted PGP key:
β ββ Base64 β rawBuffer
β ββ Parse out:
β β ββ header (45 bytes)
β β ββ ciphertext
β β ββ IV (12 bytes)
β β ββ salt (16 bytes)
β β ββ HMAC (32 bytes)
β ββ Verify:
β β ββ MAGIC == 'NP'
β β ββ VERSION supported
β β ββ header hash matches
β β ββ HMAC valid over (header + ciphertext + IV + salt)
β ββ Extract ITERATIONS & KDF_ID, derive 64-byte key via PBKDF2-SHA512
β ββ Decrypt ciphertext with AES-GCM + IV
β ββ Decompress with INFLATE (pako) β PGP key bytes
β ββ Compute its hash
ββ User clicks "import" on one PGP key
ββ Compare cloud PGP key hash against IndexedDB PGP keys to avoid duplicates
ββ Get masterKey from IndexedDB
ββ Encrypt PGP key with AES-GCM + random IV using masterKey
ββ Store the final AES-GCM-wrapped PGP key (and IV) in IndexedDB
ββ User presses lock vault button or closes tab
ββ VaultContext.lockVault()
ββ Clears encrypted vault password from React state (in-memory)
ββ Calls server API `/api/vault/lock` to revoke jwt vault session token
ββ Sets vault locked flag
Video 1 | Video 2 |
---|---|
























This project is licensed under the GPL-3.0 license.
If you have any questions, feel free to reach out:
- GitHub: XBEAST1
- Email: [email protected]
β¨ Next PGP simplifies secure messaging. Generate, manage, and encrypt with confidence! β¨