MasterSafe Authenticator: a private, offline authenticator and password vault
My desktop app for one-time codes and passwords: how it works, how the code is built, every feature, and an honest look at how secure it is.
MasterSafe Authenticator is a desktop app I build in .NET 10 for Windows and Linux. It generates the one-time codes (TOTP and HOTP) that protect your accounts and keeps them, with your passwords, in an encrypted vault on your own computer. It needs no account and no cloud, and it sends no telemetry. The only network connection it ever makes is to a backup server you choose yourself.
What the name promises and what it does not: no software is unbreakable. This page explains what MasterSafe protects, how, and where the limits are.
297
automated test methods in the repository
27 of 41
OWASP ASVS checks met in my self-assessment
0
telemetry, accounts or log files
Everything it does
All the features of the app, grouped by what they are for. The interface is in English for now.
TOTP and HOTP
RFC 6238 and RFC 4226, with SHA-1, SHA-256 or SHA-512 and 6 or 8 digits. Add accounts from an otpauth:// link or a QR code image: drag it onto the window or choose the file.
Password vault
KeePass-style entries with a password generator. Copied codes and passwords are cleared from the clipboard after 30 seconds.
Folders and bulk actions
A folder tree for passwords, with an icon for each folder chosen from a set of 24. Create, rename, move and delete folders, and select several entries to move or delete them together.
Attached files
Attach files to an entry, up to 5 MiB each and 50 MiB per vault. They stay encrypted inside the vault and are included in recovery backups.
Three ways to unlock
Master password (Argon2id), Windows Hello or a FIDO2 security key, tested with a Thales SafeNet key. Each one is a separate key slot.
Auto-lock
The vault locks after the idle time you choose. Locking wipes the key and the decrypted data from memory.
Encrypted backups
.sauth backups to a local folder or a WebDAV server such as Nextcloud or ownCloud, over https only. There is no plaintext export.
Recovery key
A recovery key and recovery backups get your data back if you forget the master password. The app can generate the passphrase for the key. There is no backdoor.
Vaults page
Shows where your files live, opens any vault file (a USB stick, another folder), and archives or deletes old vaults after a confirmation.
KeePass import
Reads KeePass and KeePassXC XML or CSV exports. Groups become folders, and files attached in XML exports come along. A summary comes first and nothing is added until you confirm.
Verifiable downloads
Every file has a SHA-256 checksum and an ML-DSA-65 post-quantum signature, and a small tool checks them all in one step.
Everyday use
System tray, light and dark themes, in-app help, and settings that are remembered between runs.
How the vault protects your data
Your accounts and passwords are encrypted with one random 256-bit data key. That key is never stored as it is. It is kept once per unlock method, in a slot, wrapped under a key that only that method can produce. So changing the master password, or adding Windows Hello, never re-encrypts the vault.
- Everything is authenticated. AES-256-GCM protects the contents, and the header and slots are bound in too, so pieces of one vault cannot be swapped into another and a slot cannot be relabelled.
- Saves are atomic. The new file is written and flushed first, then swapped in, and the previous version stays as
vault.sauth.bak. - Files are treated as untrusted. Argon2 parameters, file sizes (100 MiB for vaults and backups), decompressed size (96 MiB) and attached files (5 MiB each, 50 MiB in total) are limited before any work starts, so a crafted file cannot exhaust memory.
- A wrong key never overwrites. A save first proves the key can open the existing vault.
How the code is built
The solution is C# on .NET 10 with an Avalonia 12 (opens in a new tab) MVVM interface, split into small projects. Dependencies point one way: the domain knows nothing about the screens, and every cryptographic operation lives in one library. Windows-only code sits behind #if WINDOWS, and unlock methods implement a single interface, ISecretProvider, so the vault format does not depend on a platform.
Each project has one job, and you can read all of it on GitHub:
| Project | What it does |
|---|---|
MasterSafe.Core (opens in a new tab) | RFC 6238 TOTP, RFC 4226 HOTP, Base32, otpauth parser, account, password and attachment models, KeePass import |
MasterSafe.Crypto (opens in a new tab) | Argon2id, AES-256-GCM, vault format 3 with key slots, attachment container, atomic file repository, bounded GZip |
MasterSafe.PostQuantum (opens in a new tab) | ML-KEM-768, hybrid ECDH P-384 + ML-KEM-768, ML-DSA-65 release signing |
MasterSafe.Backup (opens in a new tab) | Password and recovery-key backups, local folder and WebDAV providers |
MasterSafe.Platform (opens in a new tab) | Windows Hello and FIDO2 unlock providers, system tray |
MasterSafe.QR (opens in a new tab) | QR decoding and generation with ZXing.Net and SkiaSharp |
MasterSafe.App (opens in a new tab) | The Avalonia desktop interface: views, view models and services |
MasterSafe.Cli (opens in a new tab) | Release tools: verify-release, verify, fingerprint, keygen, sign |
By size, the app is about 12,400 lines of C# and XAML in src, with another 6,000 lines of tests. The tests cover RFC vectors, vault security and the view models. MasterSafe.Data is a persistence library the app does not use at present.
.cs and .axaml files per project, blank lines included, at version 1.3.1. Tests are shown in grey.
Here is a small, real example of the rule that files are untrusted. Argon2 parameters come from the vault file, so Models.cs (opens in a new tab) checks them before any memory is allocated:
public void Validate()
{
if (DegreeOfParallelism is < 1 or > MaxParallelism
|| Iterations is < 1 or > MaxIterations
|| MemorySizeKib < 8 * DegreeOfParallelism
|| MemorySizeKib > MaxMemorySizeKib
|| KeyLength != 32)
{
throw new InvalidDataException("The key-derivation parameters in this file are outside the accepted range.");
}
}
Other good starting points are VaultService.cs (opens in a new tab) for the slots, HybridKemProvider.cs (opens in a new tab) for the hybrid scheme and Fido2HmacSecretProvider.cs (opens in a new tab) for security keys. No cryptographic algorithm is written by hand: they come from .NET, the operating system and a published Argon2 library.
If you forget the master password
There is no backdoor, so a lost password cannot be reset. Instead you prepare for it. On the Recovery page you create a recovery key, and now and then a recovery backup that only that key can open. Any device with the public key can write one, and no password is needed to create it. You can choose the passphrase yourself or let MasterSafe generate one: 30 random characters without look-alike letters, shown once so you can write it down.
.msrk file protected by a passphrase of at least 12 characters, and you keep that file away from this computer.
- First, try another unlock method. Windows Hello or a security key may still open the vault.
- Then, use "Forgot your master password?" on the sign-in screen to restore a recovery backup into a new vault.
- Last, start a new vault. The old one moves to an archive, it is never deleted, and it can be opened if the password turns up.
What about quantum computers?
Encrypted data stolen today could be kept and attacked later, so each part of the app was looked at separately. ML-KEM and ML-DSA come from .NET 10 and the operating system (Windows CNG, or OpenSSL 3.5+ on Linux). If the provider is missing, the code stops instead of producing weak output.
| Part | Impact of a quantum computer | Position |
|---|---|---|
| Vault at rest | Shor does not apply. Grover cuts AES-256 to about 128 bits | Safe with a strong passphrase |
| Recovery backups | Plain RSA or elliptic curves would be broken | Hybrid ECDH P-384 + ML-KEM-768: stays secret if either one survives |
| Release files | RSA or ECDSA signatures could be forged | Signed with ML-DSA-65 (FIPS 204) |
| Security key slot | Symmetric HMAC-SHA-256 inside the key | Not affected the way RSA is; the key and its PIN are still needed |
| Windows Hello slot | Uses an RSA key in the TPM | Not yet post-quantum. Safe against someone holding only the vault file. If this matters to you, do not add Hello |
So how secure is it?
The honest answer depends on who is attacking and when. This is the threat model from the repository:
| Attacker | Can they read the vault? | Why |
|---|---|---|
| Steals the vault or a backup | Only by guessing the master password | AES-256-GCM and Argon2id. A long passphrase is what matters |
| Edits the vault file | No | Everything is authenticated, so a damaged file fails closed |
| Crafts a hostile file | No | Parameters, sizes and decompression are limited first |
| Watches the network | No | Only ciphertext leaves, and WebDAV requires https |
| Malware while the vault is locked | No | Nothing on disk opens the vault without the password or the Hello prompt |
| Has your security key but not its PIN | No | The key needs its PIN and a touch, and too many wrong PINs lock it |
| Has your computer and Windows PIN | Yes, through Windows Hello | Hello is as strong as your PIN or biometrics |
| Gets a file you saved out of an entry | Yes, that file | A saved attachment is a normal file on disk, outside the vault. Delete it when you are done |
| Malware while the vault is unlocked | Yes | Software running as you can read an unlocked app. Auto-lock only shortens the window |
Slowing down password guessing
If someone steals the file, every guess at the master password has to pay the cost of Argon2id. The defaults are 128 MiB of memory, 3 passes and 4 lanes, against an OWASP minimum of 19 MiB and 2 passes. New master passwords need at least 12 characters.
Self-assessment against OWASP ASVS
I assessed the app against the parts of OWASP ASVS 4.0.3 (opens in a new tab) that apply to an offline desktop program, and the full checklist (opens in a new tab) is public. It is a self-assessment, not a certification.
Known limits
These are not hidden in small print. The repository lists them too:
- No independent security review yet.
- New master passwords are not checked against breached password lists, and there is no lock-out delay after wrong attempts in the app.
- The Windows installer is not Authenticode-signed, so SmartScreen warns about it. The ML-DSA-65 signature is how you verify it.
- Windows clipboard history may capture a copied value before it is cleared.
- The master password you type is a .NET string, which cannot be wiped from memory until it is collected.
- Hardware unlock works on Windows only, and only one security key per vault for now. On Linux the master password is the way in.
- The Linux package is built and tested in CI, but it has not been tried on a real Linux desktop yet.
In short: with a long passphrase, a stolen vault or backup is very well protected, and the network never sees your secrets. It cannot protect you from malware running as you while the vault is open. Treat it as a carefully built, openly documented personal project that has not had an outside audit yet.
How every release is checked
Many security problems in practice come from outdated parts, so the pipeline does this work on every change. A known vulnerable package fails the build, CodeQL and Gitleaks run on each push, Dependabot proposes updates, and CI generates an SBOM that is attached to the release. Each release also bundles the newest patched .NET runtime available when it is built.
Download and verify
Get version 1.3.1 from the releases page (opens in a new tab): the installer for Windows 10 and 11 (x64), or the package for Linux (x64 or arm64). No .NET installation is needed. Download every file into one folder, including masterSafe-release.pub and the MasterSafe-Cli tool, and run:
MasterSafe-Cli-1.3.1-win-x64.exe verify-release . masterSafe-release.pub
Every file must report signature valid, checksum ok, and the key fingerprint printed first must be:
28ad8deb1624d6f04fe9100e25edb2666ad904e02824af14ef2fe6c8d2a74b8a
The full steps, including how to build the checker from source, are in the README (opens in a new tab).
License and reporting a problem
MasterSafe Authenticator is freeware for personal, non-commercial use. The source is available for review and personal use, but it is not open source: commercial use and distributing modified versions are not permitted. See the license (opens in a new tab). Third-party components keep their own licenses, listed in the notices (opens in a new tab).
If you find a security problem, please use private reporting on GitHub (opens in a new tab) instead of a public issue.
Read more in the repository
- README and build instructions (opens in a new tab)
- Security model (opens in a new tab)
- Threat model (opens in a new tab)
- Post-quantum cryptography (opens in a new tab)
- Architecture (opens in a new tab)
- OWASP self-assessment (opens in a new tab)
- Roadmap (opens in a new tab)
- Changelog (opens in a new tab)