Skip to content

NextPGP is a elegant and powerful, modern online PGP tool built with Next.js. It can generate keys, manage keyrings, encrypt and decrypt messages securely and effortlessly.

License

Notifications You must be signed in to change notification settings

XBEAST1/NextPGP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Next PGP

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.


πŸš€ Features

  • 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

❓ Why Next PGP?

  • 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.

πŸ›  Tech Stack

  • 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

πŸ”’ Security

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.

⚠️ TL;DR: Although it's a web app, all cryptographic operations happen on your device. You're never sending raw passwords or secrets to the server β€” not even once. Next PGP is secure by design.


πŸ“š App Security Overview (Zero-Knowledge Architecture)

App Password Protection Setup

β”œβ”€ 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)

App Password Login

β”œβ”€ 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

App Password Removal

β”œβ”€ 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

Session Management

β”œβ”€ 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

Data Protection

β”œβ”€ PGP keys encrypted with AES-GCM + random IV
β”œβ”€ IndexedDB encryption with main crypto key
└─ Zero-knowledge architecture (client-side only)

Security Features

β”œβ”€ Web Crypto API for all operations
β”œβ”€ HTTPS enforcement
β”œβ”€ AES-GCM encryption for data protection
└─ PBKDF2 key derivation for password protection

πŸ“š Vault & Cloud Flow Overview (Zero-Knowledge Architecture)

Vault Creation

β”œβ”€ 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)

Vault Login

β”œβ”€ 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 Storage in VaultContext

β”œβ”€ Vault password stored encrypted in memory (React state)
β”œβ”€ Encryption uses separate masterKey (from IndexedDB)
└─ Password decrypted on-demand via VaultContext.getVaultPassword()

Cloud Backup

β”œβ”€ 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

Cloud Manage

β”œβ”€ 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

Vault Locking

β”œβ”€ 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

πŸ’» Click To Watch Previews

Video 1 Video 2
Next PGP Next PGP

πŸ“Έ Screenshots

πŸ’» PC

Image Image Image Image Image Image Image Image Image Image Image Image

πŸ“± Mobile

Image Image Image Image Image Image Image Image Image Image Image Image

πŸ“ License

This project is licensed under the GPL-3.0 license.


πŸ’¬ Contact

If you have any questions, feel free to reach out:


✨ Next PGP simplifies secure messaging. Generate, manage, and encrypt with confidence! ✨

About

NextPGP is a elegant and powerful, modern online PGP tool built with Next.js. It can generate keys, manage keyrings, encrypt and decrypt messages securely and effortlessly.

Topics

Resources

License

Stars

Watchers

Forks