Key points at a glance

Inlockly™ is a password manager built on a zero-knowledge model. Passwords, notes, 2FA codes, and other data in your vault are encrypted on your device before they reach the server. The server only stores and syncs ciphertext - it doesn’t know your Master Password or any key that could decrypt it.

This document explains how that works: which algorithms we use, how keys are created and protected, what happens when you sign up, sign in, unlock your vault, or change your password and email address, how access recovery and group sharing work - and what no password manager can protect against.

Property How we do it
Data encryption AES-256-GCM on your device, with a new random vector for every write
Key from password Argon2id (64 MiB, 4 iterations, 4 threads) - every attempt to guess a password is expensive
Authentication The server only receives a one-way hash, which it hashes again with BCRYPT
Sharing Group vault keys are shared using RSA-OAEP encryption (2048-bit, SHA-256)
Access recovery A recovery key known only to you; without it - an account reset with a 7-day waiting period
Second factor Email code, authenticator app, YubiKey hardware key, and backup codes
Transport Every connection to the server is encrypted with TLS
Data location Servers in the European Union

Introduction

Cybersecurity experts recommend using unique, randomly generated passwords for every account you create online. Long, complex passwords are secure, but extremely hard to remember. That’s why many people use weak, easy-to-remember passwords. A study by the UK’s National Cyber Security Centre (NCSC) found that millions of people sign in to online services with passwords containing predictable phrases, such as a pet’s name or a favorite band, as well as “password” and “123456” (see the “Standards and sources” chapter for details).

Passwords like these leave accounts exposed to attacks: cybercriminals crack weak passwords in seconds using automated tools. An 11-character password made up only of digits can be cracked almost instantly. Add lowercase and uppercase letters and special characters, and the time needed to crack it grows to decades.

Uniqueness leaves a lot to be desired, too. People often reuse one password for many accounts. Cracking that password gives a criminal access to a large amount of sensitive data, and a leak puts at risk not only you but also your company, family, or team. On top of that, workplaces often share passwords in insecure ways - in messages, spreadsheets, or on sticky notes.

Inlockly™ helps solve these problems. It provides tools for creating, storing, and sharing passwords and sensitive information for individuals and groups, while maintaining the highest level of security. Data syncs automatically and securely across every device the user has authorized.

Scope and audience

This whitepaper is intended for users, IT administrators, security teams, and auditors who want to understand how Inlockly™ protects data. It describes the application as of the release date of this version of the document. We present detailed processes in diagrams - each one comes with a step-by-step description.

Throughout the document, we capitalize the proper names of keys (for example, Master Key, Symmetric Key). You’ll find their definitions in the “Glossary” chapter.

Fundamental data protection principles

The Inlockly™ application relies on key security measures to protect all user data. These include:

End-to-end encryption

End-to-end encryption blocks access to your passwords, data, and private information through a comprehensive implementation of AES-256-GCM encryption, key derivation with Argon2id, and salted hashing. Your data is readable only on your devices.

Local-only encryption model

All cryptographic keys are generated and managed solely by the application on the user’s device. The same goes for every encryption and decryption operation - they happen locally, on an authorized device. The server doesn’t perform any cryptographic operation on vault data.

Zero-knowledge encryption

Members of the Inlockly™ team can’t see your passwords or private data. The key that opens your vault is derived from your Master Password and email address - on your device.

Your Master Password is never stored on or sent to Inlockly™ servers. The same goes for the recovery key you receive when you sign up.

Privacy by design

Inlockly™ stores your logins and private data as an encrypted vault, synced across all your devices. Before data leaves your device, it’s fully encrypted, so only you can access it. Our developers and other Inlockly™ staff have no way to read your data - even if we wanted to. Features that could reveal the contents of your vault run locally: for example, checking passwords against known breaches happens on your device, without sending passwords or their hashes to outside services.

Secure data sharing

Inlockly™ lets you create groups (family, team, company) in which users share data securely. A combination of symmetric and asymmetric encryption protects data during sharing: each member gets their own encrypted copy of the group vault key, which only they can read. The server stores these copies but can’t open them.

Security audits

We regularly review and security-test the Inlockly™ application. We run routine checks of our services and our entire infrastructure. The application complies with data protection laws, including the GDPR.

Rapid incident response

The Inlockly™ team responds to every reported incident. We investigate, analyze, and fix the bugs or potential vulnerabilities identified in a report. We inform users of every significant incident on our website and in the release notes for the new version of the app.

Bug bounty program

Inlockly™ runs a bug bounty program in which security researchers can report vulnerabilities they find. We offer rewards for finding and documenting vulnerabilities. We follow clear rules and ask researchers to practice responsible disclosure - reporting the bug to the Inlockly™ team and not disclosing it publicly until we’ve confirmed it has been fixed.

What the server sees - and what it doesn't

A zero-knowledge model doesn’t mean the server knows nothing. To sync data, manage plans, and enforce group permissions, the service needs to know some administrative information. Below, we honestly separate one from the other.

Data encrypted on your device

This data reaches the server only as ciphertext. The server has no key to read it:

Data Encrypted with
Vault item contents: name, username, password, addresses, notes, custom fields, 2FA keys Symmetric Key (private vault) or group key
Item metadata: favorites, trash, keys for active sharing links as above
Item change history (previous versions) as above
The account’s Symmetric Key Master Key (from the Master Password) and - separately - a key from the recovery key
RSA Private Key Symmetric Key
Copies of group vault keys The member’s Public Key (RSA-OAEP)
Autofill settings for websites Symmetric Key
Content shared via link A one-time link key that never reaches the server

Data the server knows

Data Why
First name, last name, and email address Account, sign-in, security notifications
BCRYPT hash of the Master Password Hash Authentication without knowing the password
Plan, subscription, billing Plan entitlements (payments are handled by a payment processor)
Names of groups, departments, and folders; memberships and permissions Access control in groups
Vault structure: item IDs, folder, author and time of change, version number Sync and change history
Devices and sessions: OS, app, IP address, approximate location, time Device limits, new sign-in alerts, activity log
Account and group activity log Transparency for users and administrators
2FA method settings Verifying the second factor (see the 2FA chapter)

What the server never receives

  • Your Master Password - not at sign-up, not at sign-in, and not when you change your password.
  • The Master Key, Symmetric Key, Private Key, or group keys in plain form.
  • Your recovery key - the server only knows a proof derived from it, stored under an HMAC seal.
  • A sharing link’s key - it’s in the part of the address after the # sign, which browsers never send.
  • Passwords being checked for breaches - the comparison happens on your device.

Cryptographic technologies

Inlockly™ uses only proven, standardized algorithms available in the platforms’ native cryptographic libraries (WebCrypto). Argon2id, which WebCrypto doesn’t offer, is implemented by the reference library compiled to WebAssembly.

Parameters at a glance

Element Algorithm and parameters
Master Key Argon2id: 64 MiB memory, 4 iterations, 4 threads, 256-bit output; salt: the first 16 bytes of SHA-256 of the normalized email address
Master Password Hash PBKDF2-SHA256, 1 iteration, payload: Master Key, salt: Master Password; 256-bit output
Password hash on the server BCRYPT, cost 12
Symmetric Key 256 bits from a CSPRNG
Data and key encryption AES-256-GCM, 96-bit nonce from a CSPRNG (new for every encryption), 128-bit tag
Ciphertext format ILK1. + nonce + ciphertext with tag (base64url)
Key pair RSA-OAEP, 2048-bit, SHA-256 (OAEP and MGF1)
Group key 256 bits from a CSPRNG
Recovery key 128 bits from a CSPRNG, written as 28 Crockford base32 characters with a 12-bit checksum
Keys from the recovery key HKDF-SHA256, empty salt, contexts “inlockly recovery v1 wrap” and “… auth”
Local unlock HMAC-SHA256 (key: Master Password Hash, message: email address)
Vault backup (.inlockly) Argon2id with a random salt and parameters stored in the file, AES-256-GCM
Transport TLS

Key hierarchy

Keys form a chain - each one is protected by the one before it. That way, changing your Master Password or email address only requires re-encrypting one short value, not your entire vault.

  1. Master Password (only in the user’s memory) → Argon2id produces the Master Key.
  2. The Master Key encrypts the account’s Symmetric Key (the Protected Symmetric Key).
  3. The Symmetric Key encrypts the items in the private vault and the RSA Private Key.
  4. The Private Key decrypts the copies of group keys, and those encrypt the items in group vaults.
  5. Independently of step 2, the recovery key encrypts a second copy of the same Symmetric Key.

AES encryption standard

The Advanced Encryption Standard (AES) is a modern symmetric block cipher - one of the most widely used in the world. It was published by Vincent Rijmen and Joan Daemen, and in 2001 it was adopted as a U.S. federal standard (FIPS PUB 197). It’s also described in ISO/IEC 18033-3.

Inlockly™ uses the AES-256 variant, where 256 is the key length in bits. Encryption with a 256-bit key consists of 14 rounds of transformations applied to each 128-bit block of data. The cipher is symmetric: the same key is used to encrypt and decrypt the data.

GCM mode

AES-256 runs in GCM (Galois/Counter Mode), defined in NIST SP 800-38D. GCM provides authenticated encryption: a single operation ensures both the confidentiality and the integrity of the data. A 128-bit authentication tag is attached to every ciphertext. Any change to the encrypted data, even a single bit, makes decryption fail, and the modified data is rejected.

Every encryption operation uses a new random 96-bit initialization vector (nonce) from a CSPRNG - even when the same item is saved again. Identical data produces a different ciphertext every time, so the encrypted form doesn’t reveal whether two items have the same content.

RSA algorithm

The Rivest-Shamir-Adleman (RSA) algorithm is one of the most widely used asymmetric cryptography algorithms. It creates two related keys: a public key that anyone can use to encrypt a message, and a private key that only its owner can use to read it. RSA’s security rests on the difficulty of factoring large composite numbers.

Inlockly™ uses RSA with a 2048-bit key and the OAEP padding scheme (Optimal Asymmetric Encryption Padding) with the SHA-256 hash function, as defined in PKCS#1 v2.2 (RFC 8017). OAEP adds randomness to every encryption and protects against known attacks on the older PKCS#1 v1.5 padding.

In Inlockly™, RSA doesn’t encrypt the data itself. It’s used only to securely hand group members the random 256-bit group vault key, which AES uses to encrypt the data. This combination, called hybrid encryption, pairs the advantages of asymmetric cryptography (no need to exchange a secret key) with the performance and strength of a symmetric cipher.

Argon2id function

Argon2 is a password-based key derivation function that won the international Password Hashing Competition in 2015. It’s standardized in RFC 9106. The Argon2id variant combines resistance to side-channel attacks with resistance to attacks using graphics cards and specialized hardware (ASICs). It’s the variant recommended by RFC 9106 and OWASP.

Unlike functions such as PBKDF2, whose cost depends only on the number of iterations, Argon2id requires a large amount of memory for every computation. An attacker trying to guess a password can’t cheaply run thousands of attempts in parallel: every attempt costs as much memory as a single user sign-in.

The parameters (64 MiB of memory, 4 iterations, 4 threads) match the configuration RFC 9106 recommends for memory-constrained devices, plus one extra iteration. They’re constants in the application and aren’t stored on the server.

PBKDF2, HKDF, and HMAC

PBKDF2-SHA256 is used only to derive the Master Password Hash from the finished Master Key, in a single iteration (see the “Creating an account” chapter). HKDF-SHA256 (RFC 5869) derives two independent keys from the random recovery key. HMAC-SHA256 lets the app verify the Master Password during local vault unlock, without involving the server.

BCRYPT algorithm

BCRYPT is a password hashing algorithm with a built-in salt and a key-stretching mechanism. The Inlockly™ server uses it to hash the received Master Password Hash again (cost 12) - so even a database leak doesn’t reveal a value that could be sent at sign-in.

Random number generation - CSPRNG

A Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) provides unpredictable values: keys, initialization vectors, and the recovery key. Inlockly™ uses the operating system’s generator exposed by the platform.

TLS protocol

TLS (Transport Layer Security), the successor to SSL, secures transmission between the app and the server (RFC 8446). In Inlockly™, it’s a second, independent layer of protection: data sent over TLS is already encrypted on the device.

Infrastructure and transport security

The Inlockly™ service runs on servers located in the European Union. The apps connect to the server only over encrypted TLS connections.

The security of vault data doesn’t depend on infrastructure: the server stores ciphertext it has no keys for. Taking over the server, a backup, or the database doesn’t give access to vault contents. Infrastructure is, however, responsible for service availability, the integrity of administrative data, and protection against abuse. That’s why the server uses, among other things:

  • attempt limits for sign-in (6 per minute from one IP address and 20 per minute for one email address), recovery, and account reset - each path has its own independent counter;
  • bot protection (Cloudflare Turnstile) at sign-up, sign-in, and when starting recovery;
  • an HMAC seal on everything that determines access (session tokens, trusted device tokens, 2FA settings, backup codes) - writing to the database without knowing the server’s secret doesn’t let anyone bypass the password or the second factor;
  • responses resistant to account enumeration - sign-up, sign-in, recovery, and reset return the same response whether or not the address has an Inlockly™ account.

Master Password

When creating an Inlockly™ account, the user sets their Master Password. It’s used for authentication, and above all, it’s the source - on the device - of the keys that open the user’s private vault and the vaults of the groups they belong to.

The vault is where logins, passwords, 2FA codes, and other sensitive data are stored. That’s why the Master Password should be strong, and the account should also be protected with two-factor authentication (2FA).

A strong Master Password

When you create an account, the app shows a password strength meter and won’t accept a password rated as weak. Your Master Password should be long and unique. A good choice is a phrase made of several random words, or a longer string of different characters: lowercase and uppercase letters, numbers, and special characters.

The strength of your Master Password directly affects the security of your data. Argon2id makes every attempt to guess the password expensive, but it’s no substitute for a good password: a short or predictable password can still be guessed despite the high cost of each attempt.

Protecting the Master Password

Encrypted vault data is useless without the key derived from the user’s Master Password and email address. The Master Password is wiped from the app’s memory right after the keys are derived and is never sent to the Inlockly™ server. The server only receives a one-way hash (the Master Password Hash), from which neither the password nor the keys can be reconstructed.

As a result, nobody on the Inlockly™ team can access your Master Password or read the encrypted data in your vault or in the vaults of the groups you belong to.

If you forget your Master Password

Because your Master Password never reaches the server, we can’t remind you of it or reset it like a typical online service would. Since version 2.1, however, you have two ways out - both consistent with the zero-knowledge model:

  • Recovery key - you receive it when you sign up. It lets you set a new Master Password and keep all your data: your private vault, your keys, and your access to groups. Described in the “Recovery key” chapter.
  • Account reset without a key - when you have neither your password nor your key. It keeps your account, plan, and group memberships, but your private vault is deleted, because nobody can decrypt it. Access to group data is restored by the group’s administrator. Described in the “Account reset” and “Restoring access to groups” chapters.

Creating an account

Sign-up is when all of an account’s keys are created. It happens entirely on the user’s device - the server only receives hashes and ciphertext.

In short:

  • the Master Key (Argon2id) and the Master Password Hash (PBKDF2) are derived from the Master Password and email address;
  • a random Symmetric Key encrypts the private vault, and is itself encrypted with the Master Key;
  • an RSA key pair lets the user securely receive group vault keys;
  • the recovery key protects a second copy of the Symmetric Key in case the password is forgotten;
  • the server hashes the Master Password Hash with BCRYPT and stores the keys unchanged - it can’t read them.

Account creation process diagram

Creating an account Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM CLIENT DEVICE - all keys are created here; the server never sees them in plaintext ENCRYPTED CONNECTION - TLS INLOCKLY SERVER 1 Derive the master key and its hash 2 Create and wrap the symmetric key 3 Create and wrap the key pair 4 Create the recovery key 5 Send hashes and ciphertext 7 Confirm, then sign in 6 Verify, hash, store - the server cannot open any key TLS OK free 201 Created REGISTER FORM ● First and last name ● E-mail address ● Master password ● Repeat master password e-mail is trimmed and lower-cased ARGON2ID Payload: ● master password Salt: SHA-256(● e-mail), first 16 B Memory 64 MiB · 4 passes · 4 lanes MASTER KEY PBKDF2-SHA256 Iterations: 1 Payload: master key Salt: ● master password MASTER PASSWORD HASH SYMMETRIC KEY 256 bits from ● CSPRNG AES-256-GCM Nonce: fresh 96-bit value from ● CSPRNG Payload: symmetric key Key: master key PROTECTED SYMMETRIC KEY ILK1.<nonce>.<ciphertext + tag> RSA-OAEP 2048 Hash: SHA-256 (OAEP and MGF1) Key pair generated on the device PRIVATE KEY AES-256-GCM Nonce: fresh 96-bit value from ● CSPRNG Payload: private key (PKCS#8) Key: symmetric key PROTECTED PRIVATE KEY ILK1.<nonce>.<ciphertext + tag> PUBLIC KEY SPKI PEM public by design REQUEST POST /users ● first and last name · ● e-mail · captcha master password hash · protected symmetric key · public key · protected private key recovery-wrapped key · recovery verifier (auth key) no key and no password leaves the device in plaintext AFTER 201 CREATED keys are wiped from memory user confirms the e-mail, then signs in CAPTCHA Cloudflare Turnstile token invalid → 422, nothing is saved ADDRESS FREE? taken: e-mail to the owner and the same 201 response no account enumeration BCRYPT (cost 12) Payload: master password hash DATABASE bcrypt hash and key blobs as received recovery verifier under an HMAC seal account inactive · activation link e-mailed RECOVERY KEY R 128 bits from ● CSPRNG shown once as 28 characters HKDF-SHA256 Input: recovery key R · empty salt info “…v1 wrap” → wrap key info “…v1 auth” → auth key AES-256-GCM Nonce: fresh 96-bit value from ● CSPRNG Payload: ● symmetric key Key: wrap key RECOVERY-WRAPPED KEY Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server ● from the form ● from device storage ● from memory ● CSPRNG
Creating an account: all keys, including the recovery key, are created on the user's device.

Account creation, step by step

Sign-up form

First, the user fills in the sign-up form, entering:

  • first and last name,
  • email address,
  • Master Password,
  • Master Password again.

The user accepts the terms of service and can opt in to marketing communications. The form is protected against bots (Cloudflare Turnstile). The Master Password is entered twice to rule out typos - the app compares both fields on the device. The strength meter shows how resistant the password is to guessing, and the app won’t accept a password rated as weak.

The email address is normalized: the app trims extra spaces and converts letters to lowercase. The same address therefore always produces the same keys, no matter how it’s typed. All the cryptographic operations described below are performed on the user’s device before any data is sent to the server.

Deriving the Master Key

The Master Key is derived locally from the Master Password using Argon2id. In a single operation, the function mixes the password with a salt and stretches it so that every attempt to guess the password is expensive. The salt is the SHA-256 hash of the normalized email address (the first 16 bytes). The other parameters: 64 MiB of memory, 4 iterations, and 4 threads. The result is a 256-bit Master Key, used to encrypt the Symmetric Key.

The Master Key is never stored on or sent to Inlockly™ servers.

Generating the Symmetric Key

The Symmetric Key is a random 256-bit value from a CSPRNG. It encrypts the data in the private vault and the Private Key. To store it securely, the app encrypts it with AES-256-GCM using these parameters:

  • initialization vector (nonce): a new random 96-bit value from a CSPRNG,
  • payload: Symmetric Key,
  • key: Master Key.

The result is the Protected Symmetric Key, which is sent to the server. Reading it requires the Master Key, and only someone who knows the Master Password can derive that.

Generating the RSA key pair

The app generates an RSA Key Pair on the device (2048-bit, OAEP with SHA-256). It’s used to securely pass along the group vault keys that let users share data with each other.

The Public Key is public by design. When User A adds User B to a group, they encrypt the group vault key with B’s Public Key and give B only the encrypted copy. Only B’s Private Key can decrypt it. The server stores this copy but can’t read it.

The Private Key decrypts the copies of group keys, and with them the data in every vault shared with the user. That’s why it’s protected just like the Symmetric Key: it never leaves the device in plain form. Before sending it to the server, the app encrypts it with AES-256-GCM using a new initialization vector, and the key is the Symmetric Key. The result is the Protected Private Key. Because it’s protected by the Symmetric Key rather than the Master Key, changing the password or email address doesn’t require re-encrypting the Private Key.

Master Password Hash

The Master Password Hash is used for authentication - the server doesn’t need the Master Password for that and never receives it. We derive it with PBKDF2-SHA256 using these parameters:

  • iterations: 1,
  • payload: Master Key,
  • salt: Master Password.

The result is a 256-bit Master Password Hash. A single iteration is a deliberate choice: Argon2id already protects against password guessing, and the Master Key the hash is derived from is a 256-bit value that can’t be guessed. The hash only needs to be one-way - a second Argon2id call would make sign-in slower with no security benefit.

Creating the recovery key

Before the account is created, the app generates a recovery key - 128 random bits from a CSPRNG. The user sees it as 28 characters in seven groups of four and has to keep it outside Inlockly™ (by copying, downloading, or printing it). The account isn’t created until the user confirms they’ve saved the key.

HKDF-SHA256 derives two independent keys from the recovery key: the wrap key encrypts (AES-256-GCM) a second copy of the Symmetric Key, and the auth key becomes a verifier that lets the server check that the user knows the recovery key without learning the key itself. Details are in the “Recovery key” chapter.

Sending the data and the server’s role

Over an encrypted TLS connection, the app sends the server the user’s first and last name, email address, and bot-protection token, plus the cryptographic material: the Master Password Hash, the Protected Symmetric Key, the Public Key, the Protected Private Key, the copy of the Symmetric Key for recovery, and the recovery key verifier. No key or password leaves the device in plain form - except the Public Key, which is public by design.

The server first checks the bot protection, then whether the email address is already taken. If it is, the server doesn’t create an account, emails the owner of the address about the sign-up attempt, and returns the same response as for a successful sign-up - so it’s impossible to tell whether a given address has an Inlockly™ account. If the address is free, the server hashes the Master Password Hash with BCRYPT (cost 12), stores the verifier under an HMAC seal, and stores the keys without any modification, because it can’t read them. The account stays inactive until the email address is confirmed with an activation link.

After receiving the response, the app wipes all keys from memory and stores nothing on the device. The user confirms their email address and then signs in as described in the “Signing in” chapter.

Signing in

Signing in happens in two steps: the server checks whether the user knows the Master Password (by comparing hashes), and the device - which has the Master Key - decrypts the account keys itself. Passing verification on the server alone isn’t enough to read any data.

In short:

  • only the Master Password Hash reaches the server - never the password or the Master Key;
  • an account with 2FA turned on requires a second factor, unless the device is trusted;
  • the server sends back the account keys only in encrypted form;
  • the device stores an HMAC code that later lets it unlock the vault without contacting the server.

Sign-in process diagram

Signing in Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM CLIENT DEVICE - master password and keys never leave the device ENCRYPTED CONNECTION - TLS INLOCKLY SERVER 1 Derive the key and the hash, send the hash 3 Decrypt the account keys 4 Prepare local unlock 5 Vault unlocked 2 Verify - the server compares hashes and never sees a key TLS OK OK 200 OK LOGIN FORM ● E-mail address ● Master password ● Trust this device (2FA) e-mail is trimmed and lower-cased DEVICE STORAGE ● Remember token only on a trusted device ARGON2ID Payload: ● master password Salt: SHA-256(● e-mail), first 16 B Memory 64 MiB · 4 passes · 4 lanes MASTER KEY PBKDF2-SHA256 Iterations: 1 Payload: master key Salt: ● master password MASTER PASSWORD HASH REQUEST POST /sessions ● e-mail + captcha master password hash ● remember token, if any 2FA step: same hash + code, no second Argon2id RESPONSE bearer token new remember token (rotated) profile with protected symmetric key and protected private key AES-256-GCM DECRYPT Ciphertext: protected symmetric key Key: ● master key (step 1) wrong key → tag check fails SYMMETRIC KEY AES-256-GCM DECRYPT Ciphertext: protected private key Key: symmetric key PRIVATE KEY HMAC-SHA256 Key: ● master password hash Message: ● e-mail → HMAC₁ lets the vault unlock without the server SAVED ON THE DEVICE ● e-mail and HMAC₁ ● bearer and remember tokens ● profile - ciphertext only never a key UNLOCKED (memory only) master key master password hash symmetric key private key CAPTCHA · BCRYPT VERIFY Turnstile or 2FA challenge token bcrypt check of the hash unknown e-mail: dummy hash, same time, same 422 message ACCOUNT CHECKS e-mail confirmed? 2FA needed? (no valid remember token) yes → 200 with a challenge; code e-mail, app, YubiKey or backup code SESSION Free plan: device limit per platform bearer token (stored under an HMAC seal) remember token rotated (HMAC seal) REPLY token and profile keys only as ciphertext Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server ● from the form ● from device storage ● from memory ● CSPRNG
Signing in: the server compares hashes and sends back keys only in encrypted form.

Sign-in, step by step

The user fills in the sign-in form with their email address and Master Password. The form is protected against bots (Cloudflare Turnstile), and the email address is normalized the same way as at sign-up.

  1. Deriving the keys and sending the Master Password Hash. The app derives the Master Key from the Master Password with Argon2id (salt: the SHA-256 hash of the email address, same parameters as at sign-up). The Master Key stays only in memory. The Master Password Hash is derived from the Master Key and the Master Password (PBKDF2-SHA256, one iteration). Over TLS, the app sends the email address, the Master Password Hash, and the bot-protection token. Neither the Master Password nor the Master Key reaches the server.

  2. Verification on the server. The server checks the bot protection and compares the received Master Password Hash with the stored BCRYPT hash. If the address doesn’t exist or the hash doesn’t match, it returns the same invalid credentials message. For an unknown address, it compares against a dummy hash, so the response time is the same - there’s no way to tell whether the address has an account. Attempts are rate-limited: 6 per minute from one IP address and 20 per minute for one email address.

    Next, the server checks whether the account’s address has been confirmed and whether the account has two-factor authentication turned on while the device isn’t marked as trusted. If so, instead of a session it returns a challenge for the second factor (see the “Two-factor authentication” chapter). The app then sends the same Master Password Hash again along with the code - without recomputing Argon2id.

    Finally, the server creates a device session, taking the plan’s device limit into account. It issues a session token, plus a trust token on a trusted device; it stores both in the database only under an HMAC seal. A successful sign-in cancels any pending account reset (see the “Account reset” chapter). In its response, it sends the tokens and account data, including the Protected Symmetric Key and the Protected Private Key - the keys only in encrypted form.

  3. Decrypting the account keys. The app decrypts the Protected Symmetric Key with AES-256-GCM using the Master Key from step 1, then uses the Symmetric Key to decrypt the Protected Private Key. The GCM authentication tag guarantees that a wrong key or a modified ciphertext results in an error, not a misread value. Authenticating with the server alone isn’t enough to read the data - you need to know the Master Password.

  4. Preparing local unlock. The app computes an HMAC-SHA256 code where the key is the Master Password Hash and the message is the email address. It stores the code, email address, tokens, and account data (encrypted only) on the device. This later lets the vault be unlocked without the server (see the “Vaults” chapter). No key is stored on the device.

  5. Vault unlocked. The Master Key, Master Password Hash, Symmetric Key, and Private Key stay only in memory. The app downloads the encrypted items and decrypts them on the device: private vault items with the Symmetric Key, and group vault items with the group keys previously decrypted with the Private Key.

Two-factor authentication (2FA)

Two-factor authentication (2FA) verifies the user with two different forms of identification: something they know (the Master Password) and something they have (an email inbox, a phone, a hardware key). Knowing the address and password is then not enough to sign in to your account.

Second-factor methods

Method How it works Availability
Email code A one-time 6-digit code sent to the account address, valid for 15 minutes Every plan
Authenticator app (TOTP) A 6-digit code that changes every 30 seconds (RFC 6238), e.g. from Google Authenticator Personal plan and up
YubiKey hardware key (OTP) A one-time password generated by a physical key when you touch it Personal plan and up
Backup codes 10 one-time codes in case you lose your phone or key Personal plan and up

You can add several methods to an account - at sign-in, the user picks whichever is convenient. Methods set up on a paid plan stay active even after moving to the Free plan: downgrading never weakens your account’s security. On the Free plan, you just can’t add a new method or generate new codes.

Second-factor safeguards

  • Attempt limit: 5 incorrect app codes or backup codes lock the second factor for 15 minutes. The counter is shared, so backup codes aren’t a second, independent way to guess. The 2FA step is only reached after a correct password, so a lockout triggers an email recommending a Master Password change.
  • Replay protection: the same app code won’t be accepted twice.
  • Backup codes use the format xxxx-xxxx, are single-use, and are stored under an HMAC seal. Using a code triggers an email with the number left; when three or fewer remain, the app recommends generating a new set. A new set fully invalidates the previous one.
  • Trusted device: after you check “Trust this device,” the server issues a trust token that skips the 2FA step on that device. The token rotates at every sign-in, and account recovery and account reset invalidate all trusted devices.

Losing your second factor

If you lose access to your authenticator app or key, sign in with a backup code and then set the method up again. Inlockly™ support doesn’t turn off 2FA manually - that kind of workaround would be a back door for anyone impersonating the account owner. The access recovery paths (recovery key and account reset) also require the second factor if the account has one.

Vaults

A vault is a set of data encrypted with the same key. After creating an account, every user becomes the owner of a private vault. Group vaults are created within groups of users (family, team, company) who share data with each other.

Encrypting data in vaults

Items in the private vault are encrypted with the user’s Symmetric Key (AES-256-GCM). This key is created when the account is set up and is protected by the Master Key derived from the Master Password.

A group vault has its own random 256-bit key, generated when the group is created. Each member gets their own copy of this key, encrypted with their Public Key (RSA-OAEP). Only that member has the Private Key that decrypts their copy, and with it, the data in the group vault.

The entire item content is encrypted (name, username, password, addresses, notes, custom fields, 2FA keys), along with its metadata and change history. Every write uses a new initialization vector.

Locking vaults

The vault locks manually, after a period of inactivity (5 minutes by default), when the screen locks, or when the system goes to sleep. Locking doesn’t sign you out of your account, but it wipes all cryptographic keys from memory. To use the app again, just enter your Master Password (or, on a phone, use biometrics).

You can change the inactivity timeout in your preferences. Instead of locking, you can also choose to sign out - then using the app again requires a full sign-in, plus the second factor if it’s turned on.

Vault unlock process diagram

Unlocking the vault Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM CLIENT DEVICE - unlocking works offline; nothing is sent to the server 1 Check the password on the device 2 Decrypt the account keys 3 Decrypt the vault 4 Lock OK biometrics UNLOCK SCREEN ● Master password the e-mail comes from storage DEVICE STORAGE ● E-mail ● HMAC₁ from the last login ● Protected keys (profile) ● Encrypted vault items BIOMETRIC UNLOCK (opt-in) phone only: Keychain / Keystore releases master key + hash after Face ID or fingerprint skips Argon2id; HMAC still checked void when biometrics change ARGON2ID Payload: ● master password Salt: SHA-256(● e-mail), first 16 B Memory 64 MiB · 4 passes · 4 lanes MASTER KEY PBKDF2-SHA256 Iterations: 1 Payload: master key Salt: ● master password MASTER PASSWORD HASH HMAC-SHA256 Key: master password hash Message: ● e-mail → HMAC₂ HMAC₁ = HMAC₂ ? ● HMAC₁ from device storage no → “wrong master password” AES-256-GCM DECRYPT Ciphertext: ● protected symmetric key Key: ● master key (step 1) tag check: second guard SYMMETRIC KEY AES-256-GCM DECRYPT Ciphertext: ● protected private key Key: symmetric key PRIVATE KEY RSA-OAEP DECRYPT Ciphertext: ● group key copies Key: private key one copy per group the user is in GROUP KEYS AES-256-GCM DECRYPT Ciphertext: ● vault items (ILK1) Key: symmetric key or group key then sync with the server UNLOCKED VAULT memory only LOCK keys wiped from memory manual, idle timer, screen lock or sleep only ciphertext stays on the device Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server ● from the form ● from device storage ● from memory ● CSPRNG
Unlocking the vault happens entirely on the device - it works even without an internet connection.

Vault unlock, step by step

A locked app shows a form where the user enters their Master Password. No email address is needed - the user hasn’t been signed out, so the address is in the device’s storage (partially masked on screen). Unlocking happens entirely on the device, without the server.

  1. Checking the password on the device. The Master Key is derived from the Master Password (Argon2id, salt from the email address stored on the device), and the Master Password Hash from that. The app computes an HMAC-SHA256 code and compares it with the code stored at the last sign-in. If the codes don’t match, it reports an incorrect Master Password and doesn’t try to decrypt the keys. The stored code doesn’t make guessing the password any easier, because every attempt requires a full Argon2id computation.
  2. Decrypting the account keys. The app decrypts the Protected Symmetric Key with the Master Key, then the Protected Private Key with the Symmetric Key. The GCM authentication tag provides a second, independent check: a wrong key or a modified ciphertext makes decryption fail.
  3. Decrypting the vaults. With the Private Key, the app decrypts (RSA-OAEP) the copies of the group keys, then the items stored locally: private vault items with the Symmetric Key, and group vault items with the matching group key. When there’s an internet connection, the app syncs the vaults with the server, sending and receiving only encrypted data.
  4. Locking. The vault stays unlocked until it’s locked manually, the inactivity timeout runs out, the screen locks, or the system goes to sleep. Locking wipes all keys from memory.

Biometric unlock

On a phone, the user can turn on unlocking with Face ID, Touch ID, or a fingerprint (Personal plan and up). Once turned on, the Master Key and the Master Password Hash are stored in the system’s hardware-protected key store (Keychain on iOS, Keystore on Android) with these safeguards:

  • the system releases them only after a successful biometric check, every time they’re used;
  • they’re never included in backups and can’t be moved to another device;
  • they’re permanently invalidated when the set of enrolled fingerprints or faces on the system changes.

Biometric unlock skips the Argon2id computation but still checks the HMAC code. After the Master Password or email address is changed on another device, the stored secret becomes outdated - the app detects this from the code mismatch, turns off biometrics, and asks for the Master Password. The secret is deleted on sign-out, when the session expires, and when the password or address changes. This is the only case in which the Master Key leaves the app’s memory - and only at the user’s explicit request.

Changing the Master Password

Changing the Master Password is fast and secure no matter how big your vault is: only the Symmetric Key

  • one short value - is re-encrypted. The data in your vaults, the Private Key, and the recovery key stay the same.

The current password is checked twice: first on the device (without contacting the server), then on the server. After the change, your other devices are signed out and the account owner gets an email notification.

Master Password change process diagram

Changing the master password Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM CLIENT DEVICE - unlocked vault; master password and keys never leave the device ENCRYPTED CONNECTION - TLS INLOCKLY SERVER 1 Verify current password (on the device) 2 Derive new keys 3 Re-encrypt the symmetric key 5 Finish 4 Verify, hash, store - the server knows only hashes and ciphertext OK TLS OK 200 OK CHANGE PASSWORD FORM ● Current master password ● New master password ● Repeat new master password new one typed twice, compared locally DEVICE STORAGE ● User e-mail ● HMAC₁ - unlock code from last login UNLOCKED VAULT (memory only) ● Symmetric key ARGON2ID Payload: ● current master password Salt: SHA-256(● e-mail), first 16 B Memory 64 MiB · 4 passes · 4 lanes CURRENT MASTER KEY PBKDF2-SHA256 Iterations: 1 Payload: current master key Salt: ● current master password CURRENT MASTER PASSWORD HASH HMAC-SHA256 Key: current master password hash Message: ● e-mail → HMAC₂ HMAC₁ = HMAC₂ ? ● HMAC₁ from device storage no → “wrong master password”, nothing is sent ARGON2ID Payload: ● new master password Salt: SHA-256(● e-mail), first 16 B Memory 64 MiB · 4 passes · 4 lanes NEW MASTER KEY PBKDF2-SHA256 Iterations: 1 Payload: new master key Salt: ● new master password NEW MASTER PASSWORD HASH HMAC-SHA256 Key: new master password hash Message: ● e-mail → new HMAC₁ AES-256-GCM Nonce: fresh 96-bit value from ● CSPRNG Payload: ● symmetric key Key: new master key NEW PROTECTED SYMMETRIC KEY ILK1.<nonce>.<ciphertext + tag> REQUEST PUT /users/profile current master password hash new master password hash new protected symmetric key vault data and private key are NOT re-encrypted AFTER SUCCESS new HMAC₁ (step 2) → ● storage new keys replace old ones in memory biometric unlock: re-enable BCRYPT VERIFY current master password hash vs stored hash mismatch → 403, nothing is saved BCRYPT (cost 12) Payload: new master password hash DATABASE new bcrypt hash new protected symmetric key AFTER COMMIT sign out other devices e-mail to the owner Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server ● from the form ● from device storage ● from memory ● CSPRNG
Changing the Master Password: only the Symmetric Key is re-encrypted - vault data stays the same.

Changing the Master Password, step by step

In account settings, the user fills in the password change form with their current Master Password and the new Master Password twice. The new password is entered twice to rule out typos - the app compares both fields on the device. The current password confirms that the account owner is making the change: first on the device, then on the server. The change happens while the vault is unlocked, so the Symmetric Key is already in memory and isn’t derived again.

  1. Verifying the current password on the device. The Current Master Key is derived from the current Master Password (Argon2id, salt from the email address stored on the device), and the Current Master Password Hash from that. The app computes an HMAC-SHA256 code and compares it with the code stored at the last sign-in. If the codes don’t match, it reports an incorrect password, and no request is sent to the server.
  2. Deriving the new keys. In the same way, the New Master Key is derived from the new Master Password (same salt, because the email address doesn’t change), along with the New Master Password Hash and a new HMAC code.
  3. Re-encrypting the Symmetric Key. The Symmetric Key is encrypted with AES-256-GCM using the New Master Key and a new initialization vector. The result is the New Protected Symmetric Key - the only element that needs re-encrypting. The Private Key and vault data are encrypted with the Symmetric Key, which doesn’t change.
  4. Verification and storage on the server. Over TLS, the app sends the Current Master Password Hash, the New Master Password Hash, and the New Protected Symmetric Key. The server re-authorizes the operation by comparing the Current Hash with the stored BCRYPT hash; if they don’t match, it rejects the request and stores nothing. After successful verification, it hashes the New Hash with BCRYPT (cost 12) and stores it along with the New Protected Symmetric Key. It then signs out the other devices and sends the owner an email notification. Throughout the process, the server works only with hashes and ciphertext.
  5. Finishing up. The app stores the new HMAC code on the device and replaces the keys in memory with the new ones. If the user was using biometric unlock, it’s turned off (the stored secret was based on the previous Master Key) - it can be turned on again in settings.

Changing the email address

The email address is the salt for Argon2id, so changing it means a new Master Key and a new Master Password Hash - even though the Master Password stays the same. The new address has to be confirmed with a code, and a notification about the change goes to both the old and the new address.

Email address change process diagram

Changing the e-mail address Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM CLIENT DEVICE - unlocked vault; master password and keys never leave the device ENCRYPTED CONNECTION - TLS INLOCKLY SERVER 1 Verify current password (on the device) 2 Confirm the new address 3 Derive new keys from the new salt 4 Re-encrypt and send 6 Finish 5 Verify, hash, store - the server knows only hashes and ciphertext OK TLS TLS OK 200 OK CHANGE E-MAIL FORM ● Current master password ● New e-mail address ● Code from the e-mail (step 2) master password stays the same DEVICE STORAGE ● Current e-mail ● HMAC₁ - unlock code from last login UNLOCKED VAULT (memory only) ● Symmetric key REQUEST CODE POST /users/verification-codes ● new e-mail address sent after step 1, before new keys ARGON2ID Payload: ● current master password Salt: SHA-256(● current e-mail), first 16 B Memory 64 MiB · 4 passes · 4 lanes CURRENT MASTER KEY PBKDF2-SHA256 Iterations: 1 Payload: current master key Salt: ● current master password CURRENT MASTER PASSWORD HASH HMAC-SHA256 Key: current master password hash Message: ● current e-mail → HMAC₂ HMAC₁ = HMAC₂ ? ● HMAC₁ from device storage no → “wrong master password”, nothing is sent ARGON2ID Payload: ● current master password Salt: SHA-256(● new e-mail), first 16 B Memory 64 MiB · 4 passes · 4 lanes NEW MASTER KEY PBKDF2-SHA256 Iterations: 1 Payload: new master key Salt: ● current master password NEW MASTER PASSWORD HASH HMAC-SHA256 Key: new master password hash Message: ● new e-mail → new HMAC₁ AES-256-GCM Nonce: fresh 96-bit value from ● CSPRNG Payload: ● symmetric key Key: new master key NEW PROTECTED SYMMETRIC KEY ILK1.<nonce>.<ciphertext + tag> REQUEST PUT /users/profile ● new e-mail + ● code current master password hash new master password hash new protected symmetric key vault data and private key are NOT re-encrypted AFTER SUCCESS new e-mail → ● storage new HMAC₁ → ● storage new keys replace old ones biometric unlock: re-enable ISSUE CODE random 6 digits, stored as bcrypt valid 15 min, max 5 attempts e-mail to the NEW address the user types it into the form VERIFY current master password hash vs bcrypt code vs stored code hash mismatch → 403 / 422, nothing is saved BCRYPT (cost 12) Payload: new master password hash DATABASE new e-mail new bcrypt hash new protected symmetric key code consumed (single use) AFTER COMMIT sign out other devices notify the old and the new address Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server ● from the form ● from device storage ● from memory ● CSPRNG
Changing the email address: a new address is a new Argon2id salt, so new keys are created.

Changing the email address, step by step

In account settings, the user enters their current Master Password, the new email address, and the verification code sent to the new address. The current password confirms that the account owner is making the change. The change happens while the vault is unlocked, so the Symmetric Key is already in memory.

Changing the email address is also a change of keys: the Argon2id salt is a hash of the email address, so the same Master Password combined with a new address gives a different Master Key.

  1. Verifying the current password on the device. The Current Master Key is derived from the Master Password (salt from the current address), and the Current Master Password Hash from that. The app compares the HMAC-SHA256 code with the code stored at the last sign-in. If the codes don’t match, no request is sent to the server.
  2. Confirming the new address. The app normalizes the new address and asks the server for a verification code. The server generates a one-time 6-digit code tied to the target address, stores only its protected form, and sends the code to the new address. The code is valid for 15 minutes and is invalidated after 5 incorrect attempts. By entering it, the user confirms access to the new inbox.
  3. Deriving new keys from the new salt. The New Master Key is derived from the same Master Password - this time the salt is a hash of the new address - and from it the New Master Password Hash and a new HMAC code.
  4. Re-encrypting the Symmetric Key and sending the data. The Symmetric Key is encrypted (AES-256-GCM) with the New Master Key and a new initialization vector. Over TLS, the app sends in a single request: the new address, the verification code, the Current and New Master Password Hashes, and the New Protected Symmetric Key.
  5. Verification and storage on the server. The server compares the Current Hash with the BCRYPT hash and checks the code. If any condition fails, it rejects the request. After successful verification, it stores the new address, the new password hash, and the New Protected Symmetric Key, consumes the code, signs out the other devices, and sends a notification to both the old and the new address - so the owner finds out about the change even if they didn’t make it themselves.
  6. Finishing up. The app stores the new address and the new HMAC code, replaces the keys in memory with the new ones, and turns off biometric unlock. At the next sign-in, the user enters the new address and their existing Master Password.

Recovery key

The recovery key lets you recover your account after forgetting your Master Password - without losing any data. It keeps your private vault, your Private Key, and your access to all your groups. Every user gets one when they sign up, on every plan.

The key doesn’t restore your old password. It opens a second, independent copy of the Symmetric Key, so the user can set a new Master Password. The server doesn’t know the recovery key - the zero-knowledge model remains intact.

What the key looks like

  • 128 random bits from a CSPRNG, generated on the device - the user doesn’t choose them.
  • Format: 28 Crockford base32 characters, in seven groups of four, with a 12-bit checksum that catches typos when the key is retyped (the checksum doesn’t add to the key’s strength).
  • When entering it, case doesn’t matter, and confusable characters are normalized (O as 0, I and L as 1).

Two keys from one secret

From recovery key R, HKDF-SHA256 (empty salt) derives two 256-bit values with different contexts:

  • the wrap key (context “inlockly recovery v1 wrap”) - encrypts, with AES-256-GCM, the copy of the Symmetric Key that is sent to the server;
  • the auth key (context “inlockly recovery v1 auth”) - proof of knowing the recovery key. The server stores it as a verifier under an HMAC seal and never returns it in any response.

Separating the contexts means the proof sent to the server can’t be used to decrypt the copy of the account key.

Account recovery process diagram

Recovering the account with the recovery key Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM CLIENT DEVICE - the recovery key and all keys stay on the device ENCRYPTED CONNECTION - TLS INLOCKLY SERVER 1 Check the key and derive its two keys 3 Open the account key 4 Set a new password and a new key 5 Unlocked 2 Verify - the server never sees the recovery key TLS OK 200 OK TLS OK 200 OK RECOVERY FORM ● E-mail address ● Code from the e-mail ● Recovery key (28 characters) ● 2FA code, if enabled ● New master password (twice) e-mail is trimmed and lower-cased FORMAT AND CHECKSUM Crockford base32 · 7 groups of 4 12-bit checksum catches typos O is read as 0, I and L as 1 RECOVERY KEY R (128 bits) HKDF-SHA256 Input: recovery key R · empty salt info “…v1 wrap” → wrap key info “…v1 auth” → auth key WRAP KEY AUTH KEY REQUEST …/verify ● e-mail + code from the e-mail auth key - proof of knowing R ● 2FA code, if required the wrap key never leaves the device RESPONSE recovery token (valid 15 min) recovery-wrapped key protected private key AES-256-GCM DECRYPT Ciphertext: recovery-wrapped key Key: ● wrap key wrong key → tag check fails SYMMETRIC KEY PRIVATE KEY CHECK decrypt the protected private key with the symmetric key proves the key really opens the account ARGON2ID · PBKDF2-SHA256 Payload: ● new master password Salt: SHA-256(● e-mail), first 16 B same parameters as at sign-in NEW MASTER KEY · NEW HASH AES-256-GCM Payload: ● symmetric key Key: new master key → new protected symmetric key NEW RECOVERY KEY R′ from ● CSPRNG, shown once HKDF → new wrap and auth keys AES-256-GCM(symmetric key, new wrap) REQUEST …/complete recovery token new master password hash new protected symmetric key new recovery-wrapped key and verifier UNLOCKED (memory only) symmetric key - unchanged private key - unchanged new master key private vault and groups kept VERIFY THE REQUEST code for this purpose only proof vs verifier (HMAC seal) unknown e-mail, wrong code or wrong proof: the same 422 SECOND FACTOR · LIMITS app, YubiKey or backup code when such a method is enabled 5 failed attempts → 15 min lock COMPLETE bcrypt(new hash), new key blobs new verifier - old key stops working all sessions and trusted devices revoked · security e-mail REPLY new session cancels a pending account reset Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server ● from the form ● from device storage ● from memory ● CSPRNG
Recovering an account with the recovery key: your vault, keys, and groups are preserved.

Account recovery, step by step

On the sign-in screen, the user chooses “Forgot your master password?” and enters their email address (the form is protected against bots). The server always responds the same way and sends a verification code only if the account exists and has a recovery key - so this can’t be used to check who has an account.

  1. Checking the key and deriving two keys. The app checks the key’s format and checksum, then derives the wrap key and the auth key. Over TLS, it sends the address, the code from the email (meant only for recovery), the auth key as proof, and - if the account has an authenticator app or a YubiKey - the second-factor code (or a backup code). The wrap key never leaves the device.
  2. Verification. The server checks the code and compares the proof with the verifier. An unknown address, a wrong code, and a wrong proof all produce the same response. Five incorrect attempts lock recovery for that address for 15 minutes. After successful verification, the server consumes the code and returns a short-lived recovery token (valid for 15 minutes), the copy of the Symmetric Key for recovery, and the Protected Private Key - keys in encrypted form only.
  3. Opening the account key. The app decrypts the copy of the Symmetric Key with the wrap key (AES-256-GCM) and checks that the Symmetric Key really does open this account’s Private Key.
  4. A new password and a new recovery key. The New Master Key and the New Master Password Hash are derived from the new Master Password - just as when changing the password. The Symmetric Key is encrypted with the New Master Key. The app also generates a new recovery key (shown once) along with a new copy and a new verifier. Everything is sent to the server together with the recovery token.
  5. Storage and a new session. In a single transaction, the server stores the new password hash and the new ciphertext, replaces the verifier (the old recovery key stops working), invalidates all sessions and trusted devices, cancels any pending account reset, and sends an email about the account recovery with details of the attempt. The app gets a new session and unlocks the vault right away.

Replacing the key and its limits

  • You can generate a new key in your account settings (requires your Master Password) - the previous one stops working completely, and the owner gets a security email.
  • Every use of the key ends with a new one being issued - the old one works once.
  • The recovery key doesn’t replace the second factor or access to your email inbox - recovery requires both if the account has 2FA turned on. That’s why you should store your backup codes so they don’t depend on a locked account.
  • Replacing the key removes its path in the service, but doesn’t undo an earlier exposure: if someone had both the recovery key and previously copied ciphertext, they could have read it outside the service.

Account reset without a recovery key

Account reset is the path for someone who doesn’t know their Master Password and doesn’t have their recovery key. It isn’t data recovery: the private vault can’t be decrypted, because nobody - Inlockly™ included - has the key to it. What a reset does is let you keep your account, email address, plan and subscription, and group memberships by creating an entirely new set of keys. Access to group data is then restored by the group’s administrator (see the “Restoring access to groups” chapter).

A reset is irreversible for the private vault, so it’s protected by a seven-day waiting period with daily notifications. An email inbox and a second factor can be lost together - for example, with a stolen phone - and the waiting period gives the owner time to react.

Account reset process diagram

Resetting the account without the recovery key Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM ACCOUNT OWNER - no master password and no recovery key INLOCKLY SERVER - 7-day grace period AFTER COMPLETION 1 Request - e-mail and the second factor 3 Finish with brand-new keys 2 Wait 7 days - the owner can cancel at any time TLS link TLS RESET FORM ● E-mail address ● Code from the e-mail ● 2FA code, if enabled no password, no recovery key REQUEST …/verify e-mail + code from the e-mail app, YubiKey or backup code if e-mail is the only method, the code already confirms it FINISH ON THE DEVICE new master password → Argon2id NEW symmetric key and RSA pair NEW recovery key nothing old can be decrypted REQUEST …/complete token from the link new hash and key blobs new public key DAY 0 · REQUEST SAVED reset possible after 7 days e-mail with attempt details and a “Not me - cancel” link DAYS 1-6 · WAITING a reminder about once a day each with “Not me - cancel” banner in signed-in apps DAY 7 · READY e-mail with “Finish the reset” the link is valid for 72 hours nothing is deleted automatically COMPLETE one transaction group managers are notified CANCELLED BY ANY OF the link in any reset e-mail “Cancel” in a signed-in app signing in (password + 2FA) recovery with the recovery key NOT FINISHED IN 72 H the request expires the account stays untouched KEPT account, e-mail, plan and subscription 2FA methods and backup codes group memberships, roles, folders group items and their share links DELETED private vault items and their history share links to those items encrypted autofill settings REVOKED all sessions and tokens trusted devices the member’s copies of group keys WAITING FOR GROUP ACCESS each group marks the member as “key reset”; a manager restores access (next diagram) Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server Deleted or revoked ● from the form
Account reset: a request, a 7-day waiting period you can cancel, and completion with new keys.

Account reset, step by step

  1. Request. The user enters their email address (the form is protected against bots) and the code sent to that address. If the account has an authenticator app or a YubiKey, they also enter the second-factor code or a backup code; when email is the only 2FA method, the code from this step already confirms it. An unknown address, a wrong code, and a wrong second factor all produce the same response, and incorrect attempts lock the path just like recovery does. Support staff can’t submit a request on the user’s behalf.
  2. Waiting period - 7 days. The server records the request and immediately sends an email with details of the attempt and a “This wasn’t me - cancel the reset” link. Over the following days, it sends a reminder roughly once a day, and signed-in apps show a banner with a cancel button. Any of the following cancels the request:
    • the link in any reset email,
    • “Cancel” in a signed-in app,
    • a successful sign-in (password and second factor) - anyone who knows the password doesn’t need a reset,
    • recovering the account with the recovery key.
  3. Completion on the device. After 7 days, the user gets an email with a “Complete reset” link, valid for 72 hours. Nothing happens automatically - if the link isn’t used, the request expires and the account stays untouched. After clicking, the app creates every key from scratch: a new Master Password and Master Key, a new Symmetric Key, a new RSA key pair, and a new recovery key (shown once). Everything is created on the device, just like at sign-up.
  4. Completion on the server. In a single transaction, the server stores the new password hash and the new keys, deletes data encrypted with the old keys, invalidates sessions, and marks group memberships as waiting for restored access. It sends an email confirming the reset, and the managers of each group get a message asking them to confirm the user’s identity before restoring access.

What a reset changes

Area Result
Account, email address, plan, subscription Kept
2FA methods and backup codes Kept - a reset isn’t a way to get around 2FA
Group memberships, roles, departments, folders, group ownership Kept
Group items and the links sharing them Untouched (encrypted with group keys)
Private vault items and their change history Deleted
Sharing links for private items, autofill settings Deleted
Sessions, tokens, and trusted devices Invalidated
This person’s copies of group keys Deleted - waiting to be restored by a manager

Sync forces a full download of the current state on every device, because local copies are encrypted with the old keys. Deleting data from the service’s database doesn’t mean it’s immediately removed from infrastructure backups - those follow a separate retention policy, and they only contain ciphertext anyway.

Restoring access to groups after a reset

After a reset, the user still belongs to their groups, with the same permissions, departments, and folders. However, their new Private Key doesn’t open the copy of the group key encrypted for their previous key pair - that copy was deleted. Access is restored by someone else who has their own working copy of the group key.

The server plays no cryptographic role in this: it doesn’t decrypt anything or generate a replacement key. The administrator also doesn’t gain access to the user’s private vault - it was lost in the reset, and nobody can rebuild it.

Access restoration process diagram

Restoring group access after a reset Inlockly™ Security Whitepaper v2.1 · master key: Argon2id · master password hash: PBKDF2-SHA256 (1 iteration) · encryption: AES-256-GCM MANAGER’S DEVICE - has its own copy of the group key RESET MEMBER’S DEVICE ENCRYPTED CONNECTION - TLS INLOCKLY SERVER - nothing is decrypted here 1 Confirm who asks 2 Open the group key 3 Wrap it for the new key 5 The member reads the group again 4 Check the permission and save OK TLS OK TLS IDENTITY CHECK outside the app: a call or a meeting in person the mailbox and the second factor may be in the wrong hands GROUP DATA own copy of the group key member’s NEW public key member marked “key reset” RSA-OAEP DECRYPT Ciphertext: own copy of the key Key: ● own private key GROUP KEY (256 bits) RSA-OAEP 2048 ENCRYPT Payload: ● group key Key: member’s NEW public key Hash: SHA-256 NEW COPY OF THE GROUP KEY REQUEST PUT …/key the new copy - ciphertext only the group key never leaves memory GROUP ITEMS READABLE AGAIN items were never re-encrypted the server never had the group key GROUP KEY RSA-OAEP DECRYPT Ciphertext: the new copy Key: ● NEW private key SYNC the member’s own copy of the group key PERMISSION CHECK “manage users” + own key copy owner reset, no other manager: any member with the key member not marked → 409 SAVE copy stored as received “key reset” mark cleared activity log · e-mail to member Legend Input / stored on device Algorithm Key or hash (memory only) Check Sent / result Server ● from memory
Restoring access to a group: a manager encrypts the group key with the member's new Public Key.

Restoring access, step by step

  1. Identity confirmation. Before restoring access, the manager should confirm the person’s identity outside the app - by phone or in person, through a channel the organization already knows. Someone who has taken over the email inbox and the second factor can look like the legitimate account owner to the service. The waiting period and notifications reduce this risk, but don’t eliminate it.
  2. Opening the group key. The manager’s app decrypts (RSA-OAEP) their own copy of the group key with their Private Key.
  3. Encrypting for the new key. The group key is encrypted (RSA-OAEP 2048, SHA-256) with the member’s new Public Key. The resulting copy is sent to the server - the group key never leaves memory.
  4. Permission check and storage. The server checks that the person restoring access has the user management permission and their own copy of the key, and that the member really is waiting for restored access (this isn’t a way to swap keys). It stores the copy unchanged, clears the flag, records the operation in the group’s activity log, and emails the member.
  5. The member can read the group again. During sync, the member’s app decrypts the new copy with their new Private Key. Group items weren’t re-encrypted - they’re readable right away.

Comparing access recovery paths

Situation What to do Private vault Groups Required
You remember your Master Password but lost the phone with your 2FA app Sign in with a backup code Kept Kept Password + backup code
You forgot your Master Password but have your recovery key Recover with the key Kept Kept Key + email code + 2FA (if turned on)
You have neither your password nor your recovery key Account reset Deleted After a manager restores access Email code + 2FA (if turned on) + 7 days
You lost your password, your key, and your second factor No self-service path - - -

Data sharing

Inlockly™ protects not only an individual user’s data, but also the exchange of sensitive information with others. Instead of sending passwords in messages, users share them in shared group vaults or with an encrypted link that expires.

Group types

Group For whom Key features
Family Loved ones, up to 5 people A shared vault; everyone also has their own private vault
Team Small teams, 5 to 10 seats Folders, permissions, activity log
Company Organizations, with no seat limit Departments, folder permissions, roles, an extended log

Every group member keeps their own private vault, which other members and administrators can’t access. Members of a company group can also create their own family group.

Encryption in groups

A group vault is encrypted with the group’s own random 256-bit key. When a new person joins the group, a member with the right permission approves them, and their app encrypts the group key with the new person’s Public Key (RSA-OAEP) and sends only that encrypted copy. The server never knows the group key.

Permissions (who can see which folder, who can edit, share, or manage members) are enforced by the server. The group is always determined on the server side from the resource the request acts on - a permission in one group doesn’t allow operations in another.

Joining groups

You join a group with a join code or a link from an invitation emailed by a member with the right permission. Codes and invitations are valid for a limited time. Joining requires approval - only then does the new member receive the encrypted copy of the group key.

A single item can be shared with someone outside your account using an encrypted link (Personal plan and up):

  • the item’s content is encrypted (AES-256-GCM) with a new random key just for that link;
  • the key is part of the address after the # sign - browsers never send that part to the server, so the server only stores ciphertext;
  • the link lasts from one hour to 30 days, or is one-time - it expires after it’s first opened;
  • access can be limited to specific email addresses - the recipient then confirms their address with a code;
  • once the link expires or is used up, the server deletes the ciphertext, and only a record of the link (without content) stays in the history; you can also revoke a link at any time.

Vault backup

Exporting to an .inlockly file creates an encrypted backup with a separate password: the key is derived with Argon2id using a random salt and parameters stored in the file, and the content is encrypted with AES-256-GCM. The backup opens independently of the account. A wrong password and a corrupted file are indistinguishable.

Helper features and privacy

Some app features need data from the vault. We design them so that this data never leaves the device.

SafetyMeter™

SafetyMeter™ rates password strength and points out reused passwords, websites without an encrypted connection, and accounts where it’s worth turning on 2FA. Checking passwords against known breaches happens on the device: the app compares passwords with a bundled list of about 100,000 passwords from public breaches. We don’t send passwords or their hashes to outside services. The results are calculated in memory and never reach the server.

2FA codes in items

A 2FA key saved with a login is part of the item’s encrypted content. The one-time code (RFC 6238) is calculated by the app on the device - the server knows neither the key nor the codes.

Autofill

The browser extension and system autofill on phones fill in forms locally. Autofill settings for individual websites are encrypted with the Symmetric Key. System autofill on a phone unlocks the vault with the same Argon2id function as the app.

Website icons

The app shows website icons next to items. It fetches them through an Inlockly™ proxy server instead of directly from outside services, so the list of your websites doesn’t reach third parties. The proxy only learns the name of the website whose icon the app is requesting. Icons are cached on the device, and you can turn them off completely in your preferences - then the app sends no requests at all.

Item change history

Previous versions of an item are stored encrypted with the same key as the item. The server only knows the time and author of each change, which are needed for sync and the activity log. How long history is kept depends on the plan.

Threat model and the limits of protection

No system protects against everything. Below, we describe what Inlockly™ protects against, and in which situations protection depends on the user and their device.

What Inlockly™ protects against

Threat Why your data stays safe
A leak of the server’s database or backups The database contains ciphertext and BCRYPT hashes; keys are derived only from the Master Password or the recovery key
A compromised server or a dishonest employee The server doesn’t know the keys; it could block the service, but it can’t read vaults
Eavesdropping on the connection TLS, and beneath it, data already encrypted on the device
Tampering with encrypted data The GCM authentication tag - modified ciphertext won’t be accepted
Guessing the Master Password from stolen data Argon2id (64 MiB per attempt) and BCRYPT on the server
Signing in with someone else’s password A second factor, new device alerts, attempt limits
Checking whether someone has an account The same responses and timing for existing and nonexistent addresses
Bypassing 2FA with a database write An HMAC seal on everything that determines access
Taking over an inbox and second factor to force a reset A 7-day waiting period, daily notifications, and one-click cancellation

The limits of protection

  • An infected device. Malware with full access to an unlocked device (for example, a keylogger) can capture the Master Password or read data from an unlocked vault. Keep your system up to date, and don’t install software from untrusted sources.
  • A weak or reused Master Password. Argon2id raises the cost of an attack, but it’s no substitute for a good password.
  • Phishing. A fake site can trick you into entering your Master Password. The Inlockly™ extension only suggests data on the correct domain - if no suggestion appears, check the address.
  • Losing every factor. Without the Master Password, the recovery key, and the second factor, there’s no self-service path to recover the account.
  • Metadata. The server knows the administrative information described in the “What the server sees” chapter - including group and folder names, the time of changes, and device IP addresses.
  • People with access to a group. A group member can read and copy the data they have access to. Revoking access doesn’t delete copies they’ve already made - after someone leaves, change the passwords that were shared with them.
  • The account’s TOTP secret. A second factor in an authenticator app requires the server to know its secret (encrypted with a server key). This doesn’t affect the confidentiality of the vault.

Recommendations

For users

  • Choose a long, unique Master Password and don’t use it anywhere else.
  • Keep your recovery key outside Inlockly™ - printed, or on a storage device somewhere safe.
  • Turn on two-factor authentication - ideally an authenticator app or a YubiKey - and store your backup codes independently of your phone.
  • Respond to security emails: a new sign-in, a reset request, a backup code being used. If it wasn’t you, cancel the request and change your Master Password.
  • Set a short auto-lock timeout on devices that other people also use.
  • Check SafetyMeter™ regularly and change weak, reused, and breached passwords.

For group and company administrators

  • Create a procedure for confirming identity before restoring access after an account reset - outside the app, through a channel you already know.
  • Make sure at least two people have the user management permission and a copy of the group key. Resetting the only manager makes restoring access harder, and resetting the only person with the key means losing the group’s data.
  • Grant permissions on a need-to-know basis: folder and department access only for those who need it.
  • Don’t put sensitive information in the names of groups, departments, and folders - they aren’t encrypted.
  • When an employee leaves, remove them from the group and change the passwords that were shared with them.
  • Review the group’s activity log, especially after a member’s account reset.
  • Remind members to keep their recovery key - it’s the simplest way to avoid losing data.

Glossary

Term Meaning
Master Password A password known only to the user; it never reaches the server
Master Key A 256-bit key derived from the Master Password with Argon2id; kept only in the device’s memory
Master Password Hash A one-way hash of the Master Key sent to the server for authentication
Symmetric Key A random 256-bit account key; it encrypts the private vault and the Private Key
Protected Symmetric Key The Symmetric Key encrypted with the Master Key; stored on the server
RSA Key Pair A Public Key (public) and a Private Key; used to pass along group keys
Protected Private Key The Private Key encrypted with the Symmetric Key; stored on the server
Group key A random 256-bit group vault key; each member has their own encrypted copy
Recovery key 128 random bits (28 characters) for recovering an account after forgetting the Master Password
Wrap key / auth key Keys derived from the recovery key: the first encrypts a copy of the Symmetric Key, the second is proof for the server
Verifier A value that lets the server recognize a correct recovery key without knowing the key
Vault A set of items encrypted with the same key: private or group
Item A single entry in the vault: a login, card, note, and so on
Nonce (initialization vector) A random, single-use value used for every AES-GCM encryption
Authentication tag A 128-bit GCM value that detects any change to the ciphertext
HMAC seal A server signature that protects access-determining data from modification in the database
Session token An identifier for a signed-in device
Trust token Skips the 2FA step on a trusted device
Waiting period The 7 days between an account reset request and the ability to complete it
CSPRNG A cryptographically secure random number generator
Zero-knowledge A model in which the service provider has no keys to the user’s data

Standards and sources

Changelog

v2.1 - October 5, 2026

This whitepaper describes new access recovery paths and has a new format: a web version and a PDF generated from the same content. The fundamental data protection principles and the cryptographic scheme from version 2.0 remain unchanged.

  • Recovery key (new chapter and diagram): a 128-bit key created at sign-up lets you recover your account after forgetting your Master Password without losing data. We removed statements saying access couldn’t be recovered.
  • Account reset without a recovery key (new chapter and diagram): a 7-day waiting period with notifications and the option to cancel; the private vault is deleted, while the account, plan, and memberships stay.
  • Restoring access to groups after a reset (new chapter and diagram) by a group manager, along with the identity confirmation principle and the exception for the group owner.
  • Two-factor authentication: added authenticator apps (TOTP) and 10 backup codes, plus a description of attempt limits, replay protection, and method availability by plan.
  • The account creation diagram now includes recovery key generation; the sign-in descriptions are updated (session and trust tokens under an HMAC seal, cancellation of a pending reset).
  • New chapters: “Key points at a glance,” “What the server sees - and what it doesn’t,” a summary of cryptographic parameters and the key hierarchy, sharing via link and vault backup, helper features and privacy, the threat model, recommendations for users and administrators, a glossary, and standards and sources.
  • The infrastructure chapter is limited to the current state (servers in the European Union); we’ll publish a detailed description of the architecture in the next version.
  • Diagrams in Polish and English, generated from a single model.

v2.0 - September 24, 2026

The second version of the Inlockly™ Security Whitepaper. The fundamental data protection principles remain unchanged, but their cryptographic implementation has changed. The new scheme isn’t compatible with the one described in version 1.0.

  • We derive the Master Key with Argon2id (64 MiB, 4 iterations, 4 threads) instead of PBKDF2-SHA256. The salt is the SHA-256 hash of the email address. PBKDF2 is now used only to derive the Master Password Hash, in a single iteration.
  • We encrypt data and keys with AES-256-GCM, which detects any modification of encrypted data. A new initialization vector is generated for every encryption.
  • The Symmetric Key is 256 bits long.
  • We protect copies of group vault keys with RSA-OAEP (2048-bit, SHA-256).
  • The default inactivity period after which vaults lock is 5 minutes.
  • We updated the description of the technology (TLS instead of SSL) and of data protection regulations, removed the description of regenerating the Symmetric Key, and fixed editorial errors.

v1.0 - January 13, 2024

The first public release of the Inlockly™ Security Whitepaper. This document helps you understand how we implemented every solution in Inlockly™, and how we take care of your data and sensitive information.