gcrypt is a Windows desktop Google Drive sync client with client-side encryption. All files are encrypted locally before being uploaded to Google Drive, ensuring that no plaintext data ever leaves your machine.
- Features
- Security Model
- Installation
- Google Drive API Setup
- Usage
- Accessing Your Sync on Another PC
- Configuration
- Architecture
- Troubleshooting
- Development
- Contributing
- License
- End-to-End Encryption β Files are encrypted with AES-256-GCM before upload. Each file gets a unique Data Encryption Key (DEK), wrapped by a Key Encryption Key (KEK) derived from your passphrase.
- Multi-Sync Support β Sync multiple directory pairs simultaneously, each with independent configuration.
- System Tray Integration β Monitor status, manage sync pairs, and configure settings from the Windows system tray.
- Real-Time Sync β Automatically detects local file changes and syncs them to Google Drive.
- Per-File Encryption Keys β Each file uses a unique DEK, ensuring key isolation.
- Filename Encryption β Filenames are encrypted with deterministic nonce based on file path, enabling safe syncing while preserving searchability.
- Auto-Start with Windows β gcrypt starts automatically with your session.
- Batch Operations β Pause/Resume All, Sync All Now for quick management.
- Configurable Sync Intervals β Per-pair and global sync interval settings.
- Large File Support β Configurable maximum file size limits.
- Comprehensive Logging β Detailed logs with configurable levels and rotation.
Passphrase + Salt (16 bytes)
β
βΌ
Argon2id (memory=64 MiB, iterations=3, parallelism=4)
β
βΌ
Master Key (256 bits / 32 bytes)
Each file gets its own unique DEK:
Random DEK (256 bits)
β
βΌ
Encrypt with Master Key (AES-256-GCM)
β
βββΊ Encrypted DEK (48 bytes: 32 ciphertext + 16 tag)
βββΊ DEK Nonce (12 bytes, random)
File Content + DEK + FilePath
β
βΌ
Hash FilePath (SHA-256) β AAD
β
βΌ
Generate Content Nonce (12 bytes, random)
β
βΌ
Encrypt with AES-256-GCM (AAD = SHA-256(filePath))
β
βββΊ Content Nonce (12 bytes, stored in header)
βββΊ Ciphertext (includes 16-byte GCM tag)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Magic (6 bytes): "GCRYPT" β
β Version (2 bytes): 0x0001 β
β Encrypted DEK (48 bytes): AES-GCM ciphertext + tag β
β DEK Nonce (12 bytes): Random nonce for DEK decryption β
β Content Nonce (12 bytes): Random nonce for file content β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Ciphertext (variable): File content + 16-byte GCM tag β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Feature | Implementation |
|---|---|
| Key Derivation | Argon2id (RFC 9106) |
| Encryption | AES-256-GCM (NIST SP 800-38D) |
| Master Key Protection | Windows VirtualLock + NOOVERWRITE |
| Nonce Generation | crypt/rand (OS entropy) |
| File Binding | SHA-256(filePath) as AAD |
| Filename Encryption | AES-256-GCM with deterministic nonce |
- Windows 10 or later (64-bit)
- Google account with Drive access
- Go 1.26.4 or later (for building from source)
- GCC compiler (e.g., MinGW-w64) with
cgosupport enabled (required by the Fyne GUI package)
Because gcrypt uses the Fyne GUI toolkit, building requires CGO. Additionally, on Go 1.26+, a clang-only compilation flag causes default GCC builds to fail. To automate building the custom compiler wrapper and compiling gcrypt as a background GUI process, use the provided PowerShell build script:
# Clone the repository
git clone https://github.com/yourusername/gcrypt.git
cd gcrypt
# Run the build script (compiles the gcc wrapper and gcrypt.exe)
powershell -File .\build.ps1
# Run setup (first time only)
./gcrypt.exe -setupTo use gcrypt, you need to set up a Google Cloud project with the Google Drive API enabled and configure OAuth client credentials. Follow these detailed steps:
- Open the Google Cloud Console.
- Click the project dropdown in the top-left corner and select New Project.
- Enter a project name (e.g.,
gcrypt-sync) and click Create.
- Navigate to APIs & Services > Library using the left sidebar.
- Search for Google Drive API.
- Click on the Google Drive API result and click Enable.
- Go to APIs & Services > OAuth consent screen in the left sidebar.
- Select External as the User Type (this allows you to use your personal Google account) and click Create.
- Provide the required App Information:
- App name:
gcrypt - User support email: Select your email address.
- Developer contact information: Enter your email address.
- Click Save and Continue.
- App name:
- Configure Scopes:
- Click Add or Remove Scopes.
- Under Manually add scopes, enter:
https://www.googleapis.com/auth/drive.file - Click Add to Table and click Update.
- Click Save and Continue.
π Privacy Note:
gcryptuses the narrowdrive.filescope. This means it can only access files and folders that it creates or that the user explicitly opens with it. It cannot read, modify, or delete any other files in your Google Drive.
- Configure Test Users:
- Google restricts unverified apps in "Testing" status to specific authorized users.
- Click Add Users and enter the email address of the Google Account you wish to sync files with.
- Click Save and Continue, review the summary, and return to the dashboard.
- Navigate to APIs & Services > Credentials in the left sidebar.
- Click + Create Credentials at the top of the page and select OAuth client ID.
- Select Application type: Web application.
βΉοΈ Why Web application?
gcryptlistens on a local loopback port (http://localhost:8089/callback) to receive the OAuth authorization code after you sign in via your web browser. A Web Application client ID is required to register this redirect URI. - Enter a name (e.g.,
gcrypt-client). - Under Authorized redirect URIs, click + Add URI and enter exactly:
http://localhost:8089/callback - Click Create.
- Copy the generated Client ID and Client Secret. Keep these secure.
You can provide these credentials to gcrypt in one of two ways:
When you run ./gcrypt.exe -setup (or when prompted by the system tray GUI on first launch), you will be asked to enter the Client ID and Client Secret. gcrypt will encrypt the secret using your passphrase-derived master key and persist both in your config file (%APPDATA%\gcrypt\config.yaml):
oauth:
client_id: "YOUR_CLIENT_ID"
client_secret_enc: "ENCRYPTED_SECRET_BASE64"If you prefer not to store credentials in your configuration file, you can set them as environment variables before starting gcrypt. This is especially useful for Docker container deployment or scripts:
- PowerShell / Windows Terminal:
$env:GCRYPT_OAUTH_CLIENT_ID="your-client-id" $env:GCRYPT_OAUTH_CLIENT_SECRET="your-client-secret" ./gcrypt.exe
- Windows Command Prompt (CMD):
set GCRYPT_OAUTH_CLIENT_ID=your-client-id set GCRYPT_OAUTH_CLIENT_SECRET=your-client-secret gcrypt.exe
- Linux / Docker (if applicable):
export GCRYPT_OAUTH_CLIENT_ID="your-client-id" export GCRYPT_OAUTH_CLIENT_SECRET="your-client-secret"
When these environment variables are set, they take precedence over config settings and bypass the credential prompt.
# Run with default config
./gcrypt.exe
# Run with custom config path
./gcrypt.exe -config C:\path\to\config.yaml
# Run first-time setup
./gcrypt.exe -setupgcrypt automatically adds itself to Windows startup. Enable/disable in:
- Settings β Apps β Startup β gcrypt
- Or via the main window's Settings tab: Auto-start with Windows
gcrypt runs in the background. Its status is represented by the system tray icon, and inside the main GUI window by a colored status dot and label:
| App State | Tray Icon File | System Tray Icon | GUI Status Dot Color | GUI Status Label | Meaning / Action Required |
|---|---|---|---|---|---|
| Not Configured | warning.png |
π‘ Warning | π Gray | "Not configured" | The app has not been set up yet. Run the setup wizard. |
| Locked | warning.png |
π‘ Warning | π‘ Amber | "Locked" | Master key is not decrypted. Enter your passphrase to unlock. |
| Sign In Required | warning.png |
π‘ Warning | π΄ Red | "Sign in required" | OAuth token is missing or expired. Click to sign in. |
| Connecting | syncing.png |
π΅ Syncing | π΅ Blue | "Connectingβ¦" | Establishing connection to Google Drive API. |
| Scanning | syncing.png |
π΅ Syncing | π΅ Blue | "Scanningβ¦" | Scanning local/remote directories for changes. |
| Syncing | syncing.png |
π΅ Syncing | π΅ Blue | "Syncingβ¦" | Uploading or downloading files. |
| Idle | synced.png |
π’ Synced | π’ Green | "Up to date" | Synchronized and idle. |
| Error | error.png |
π΄ Error | π΄ Red | "Error" | Critical error occurred. Check the log file for details. |
| Disconnected | error.png |
π΄ Error | π΄ Red | "Disconnected" | Network offline or connection timed out. |
Right-clicking the tray icon opens a quick-access menu:
Open gcrypt <-- Opens the main GUI flyout window
βββββββββββββββββββββββ
Sync All Now <-- Force scan and sync of all folder pairs
Pause All / Resume All <-- Toggle sync state globally
Open Sync Folder <-- Open local sync directory in Explorer
View Log <-- Open log file in Notepad
βββββββββββββββββββββββ
Quit <-- Gracefully stop sync engines and exit
Left-clicking the tray icon (or selecting Open gcrypt) opens a flyout window similar to Nextcloud, containing the following tabs:
- Activity β Shows a real-time list of synced files, errors, and progress.
- Folders β Shows status of individual sync pairs, allowing per-pair Pause/Resume, Sync Now, Open Folder, and Remove options.
- Settings β Allows managing global parameters such as:
- Auto-start with Windows
- Remember passphrase (auto-unlock via Windows DPAPI)
- Sync Interval
- Max File Size limit
- Log settings (Level, Max Size, Max Backups)
- Bandwidth Rate Limits (Upload/Download in KB/s)
Your encrypted files in Google Drive can only be decrypted with the master key, and that key is derived from both your passphrase and a random 16βbyte salt:
Master Key = Argon2id(passphrase, salt)
Warning
CRITICAL: BACK UP YOUR SALT AND PASSPHRASE!
Because gcrypt derives the master key locally from both your passphrase and salt.bin (which is never uploaded to Google Drive for security reasons), you MUST back up both your passphrase and the salt.bin file.
If you lose both your passphrase and your salt.bin file, YOUR ENCRYPTED DATA CAN NEVER BE RECOVERED. There is no password reset, recovery key, or back door. Keep a copy of salt.bin in a safe, offline location (like a USB drive or password manager).
The salt is generated once, on the PC where you first set up the sync, and is stored locally at %APPDATA%\gcrypt\salt.bin. It is never uploaded to Google Drive. This means a second computer cannot simply install gcrypt and run a normal setup β doing so would generate a different salt, derive a different master key, and fail to decrypt anything in the cloud.
To use the same encrypted sync on another PC you must import the original salt and identity. gcrypt's setup has a builtβin path for this.
| Item | Where it comes from |
|---|---|
| Your passphrase | You type it (it is never stored) |
The salt (salt.bin) |
Copied from the first PC |
| Drive folder ID + OAuth client credentials | Read from the first PC's config.yaml |
| A fresh Google signβin (OAuth token) | Done on the new PC during setup (tokens are perβdevice) |
| A local folder to sync into | Chosen on the new PC |
-
On the first PC, open
%APPDATA%\gcrypt\and copy these two files to the second PC (USB stick, temporary folder, etc.):config.yamlsalt.bin
π
salt.binis not secret, butconfig.yamlcontains your encrypted OAuth client secret and token settings. Treat the copy with care and delete the transfer copy when you're done. -
On the second PC, install/launch gcrypt and start setup (tray β Run Setupβ¦, or
gcrypt.exe -setup). -
When asked "Is this the FIRST computer you are setting up gcrypt on?", choose No.
-
Select the folder where you placed the copied
config.yamlandsalt.bin. -
Enter the same passphrase you use on the first PC. gcrypt reβderives the master key from the imported salt and verifies it against the imported passphrase hash.
-
Complete the Google signβin in the browser when prompted (use the same Google account). This creates a new perβdevice token.
-
Choose a local folder on this PC to sync into. It starts empty and is populated by downloading and decrypting your files from Google Drive.
That's it β the second PC now shares the same encrypted sync. Changes made on either machine propagate through Google Drive to the other.
- The passphrase must match exactly. There is no recovery if the salt is lost and you no longer have any configured PC β keep a backup of
salt.binsomewhere safe (it is useless without your passphrase). - Each PC signs in to Google separately. OAuth tokens are stored encrypted per device and are not copied.
- The local sync folder path is perβmachine; it does not need to match the first PC.
- If you only ever set up gcrypt fresh on the second PC (choosing Yes), it will create a separate sync with its own salt β it will not be able to read the first PC's encrypted files. Always use the No / connect to existing path to share a sync.
%APPDATA%\gcrypt\config.yaml
version: 2
sync_pairs:
- id: "uuid-v4-here"
local_dir: "C:\\Users\\username\\Documents"
drive_folder_id: "drive-folder-id"
enabled: true
sync_interval: 30
app:
auto_start: true
log_level: "info"
max_file_size: 104857600
upload_workers: 160 # max concurrent small-file uploads per pair (0 = default of 160)Throughput tuning (
upload_workers): uploads run in parallel, so syncing large trees of small files (e.g.node_modules) is bound by how many files upload concurrently. Each small upload takes ~1s against Drive, so throughput βupload_workersfiles/sec β to approach Drive's request-rate ceiling you need roughly that many workers in flight, which is why the default is 160. The pool is load-adaptive β only as many workers as there is work run at once, scaling up toupload_workersand back down when the backlog drains, so a high value costs nothing when idle. Large files (β₯ 8 MiB) are separately capped at 3 concurrent uploads so they can't exhaust memory or bandwidth or starve the small-file uploads. The per-pair Drive request rate is capped automatically at ~180/s (β90% of Google's ~200/s per-user limit; rate-limited requests are retried with backoff). This cap is per sync pair β lowerupload_workersif you run many pairs or still hit rate limits on a constrained connection.
gcrypt mirrors your local directory tree on Drive as a chain of encrypted subfolders. Each local subdirectory becomes a Drive subfolder whose name is the encrypted directory name, and each file is stored under its encrypted parent folder with only its (encrypted) basename. This preserves folder structure remotely while keeping everything encrypted, and prevents any single Drive folder from growing without bound. Folder IDs are cached in memory and created on demand. When a deletion empties an encrypted folder, gcrypt removes it (and any newly empty parent folders) from Drive automatically.
The application consists of a SyncManager coordinating multiple independent Engines. Each engine manages a specific local-to-remote directory pair.
SQLite is used for local state tracking, mapping local files to encrypted remote objects.
-
Red Icon (Error / Disconnected): A critical synchronization error occurred or the network is offline. Check the log file (
%APPDATA%\gcrypt\gcrypt.log) for error details. -
Yellow Icon (Warning): Action is required to resume sync. Open the gcrypt GUI panel to run setup, unlock the app using your passphrase, or authenticate with Google.
-
Database Error: Try deleting the local state database at
%APPDATA%\gcrypt\gcrypt.dband restarting the application to rebuild the local file metadata cache. -
Tray icon works but the window never opens (especially over Remote Desktop): The GUI renders with OpenGL, and Remote Desktop sessions, many VMs, and machines with broken GPU drivers expose no usable hardware OpenGL. The log will show
Fyne error: window creation error β¦ WGL: The driver does not appear to support OpenGL. Fix: install a software OpenGL renderer once by runninginstall-mesa.ps1:pwsh -ExecutionPolicy Bypass -File .\install-mesa.ps1
This downloads Mesa3D (llvmpipe) and places its DLLs in a
mesa\folder next togcrypt.exe. gcrypt then detects inadequate OpenGL automatically (RDP / VM / bad drivers), switches to software rendering and relaunches β the window opens normally. Machines with a working GPU keep using hardware OpenGL and ignore the bundled Mesa. (To force software rendering everywhere, copy themesa\*.dllfiles directly next togcrypt.exe.)
cmd/gcrypt/: Application entry point and setup wizard.internal/sync/: Core sync engine and multi-pair manager.internal/crypto/: AES-GCM and Argon2id implementations.internal/drive/: Google Drive API integration.internal/service/: Windows system tray and OS integration.
- Go Version: Requires Go 1.26.4+.
- Linting: Uses
golangci-lint. - Security: Uses
gosec,govulncheck, andgitleaks.
# Run with Race Detector
go test -race ./...
# Run Performance Benchmarks
go test -bench=. ./internal/sync/
# Generate Coverage Report
go test -coverprofile=coverage.txt ./...We welcome contributions! Please see CONTRIBUTING.md for guidelines. For security-related issues, please refer to our Security Policy.
MIT License - Copyright (c) 2026 gcrypt contributors
For issues and feature requests, please open an issue. Join our Discord server for real-time help.
gcrypt v0.1 - The encrypted Google Drive sync client for Windows
