This document provides a high level overview of the security design and architecture of the Padloc application.
While the secure processing, storage and sharing of sensitive data necessarily involves a certain degree of complexity, Padloc tries to hide this complexity from the end user as much as possible. In other words, users should be able to use the application securely without understanding (or even being aware of) the underlying security principles. At the same time, the applications inner workings and security mechanisms should be easily verifiable by those who have the technical knowledge to do so, which brings us to...
It is a widely know fact among security experts that Security through Obscurity is not only ineffective, but can in fact be harmful if used to cover up otherwise sloppy security practices. We believe that full transparency is not only the best foundation for trust, but also allows us and other independent reviewers to discover and fix any potential security flaws and efficiently as quickly as possible.
While Padlocs open source nature is helpful in uncovering unintended vulnerabilities in the source code, it is, by itself, insufficient for verifying that the code actually deployed in production is not altered in a way that may compromise the security of the application either intentionally or unintentionally. This is why we take additional steps to make sure that some parts of the architecture can in fact be verified in production, while others do not need to be verified by design (see Possible Attack-Vectors And Mitigations). This means that unlike other products, Padloc does not require explicit trust between the end user and the host.
Robust data encryption is the foundation of Padlocs security architecture. Padloc utilizes three basic encryption schemes.
This is the most basic encryption scheme used in Padloc. Simple encryption employs a symmetric cipher to encrypt the provided data with a randomly generated key. The encrypted data, along with the encryption parameters needed for decryption, is stored in a container object, which can then be stored or transmitted securely. Padloc currently uses the AES cipher in GCM mode, but other options may be added in the future.
- Choose a random encryption key
k
- Choose a random initialization vector
iv
and additional dataa
(for authenticated encryption modes) - Generate the encrypted data
c = AES_encrypt(k, p, iv, a)
from the plain textp
- Store
c
,iv
anda
in the containerC
┌───────────┐ ┏━━━━━━━━━━━━━━━━┓
========= │ │ ┃Simple Container┃ ╔═══════════╗
== key ==─────┘ ▼ ┃ ┃ ║ encrypted ║
========= ┌─────────┐ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ ╚═══════════╝
│ encrypt │ ┃ encryption │┃ ┌ ─ ─ ─ ─ ─ ┐
┌────▶│ (AES) │────────────▶│ parameters ┃ plain
│ └─────────┘ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ └ ─ ─ ─ ─ ─ ┘
============== │ │ ┃╔══════════════╗┃ =============
= plain text =────┘ └─────────────────▶║encrypted data║┃ = ephemeral =
============== ┃╚══════════════╝┃ =============
┗━━━━━━━━━━━━━━━━┛
- Let
k
be the key used for encryption. - Retrieve
iv
,a
andc
fromC
- Generate the plain text
p = AES_decrypt(k, c, iv, a)
In the password-based encryption scheme (based on the PBES2 standard) an encryption key is derived from a user password using the PBKDF2 key derivation function.
- Choose a password
p
- Choose an iteration count
i
and random salts
- Generate
k = PBDKF2(p, s, i)
- Choose a random initialization vector
iv
and additional dataa
(for authenticated encryption modes) - Generate the encrypted data
c = AES_encrypt(k, p, iv, a)
from the plain textp
- Store
s
,i
,c
,iv
anda
in the containerC
============ ┌────────┐ ┏━━━━━━━━━━━━━━━━┓
= password =──────────▶│ PBKDF2 │───────┐ ┃ Password-Based ┃
============ └────────┘ │ ┃ Container ┃
│ │ ┃ ┃
│ │ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
▼ │ ┃ PBKDF2 │┃
========= └──────▶│ parameters ┃
== key == ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
========= ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
│ ┃ encryption │┃
▼ ┌──────▶│ parameters ┃
┌─────────┐ │ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
============== │ encrypt │ │ ┃╔══════════════╗┃
= plain text =─────────▶│ (AES) │──────┘┌─────▶║encrypted data║┃
============== └─────────┘ │ ┃╚══════════════╝┃
│ │ ┗━━━━━━━━━━━━━━━━┛
│ │
└────────────┘
- Let
p
be the password used for encryption - Retrieve
s
,i
fromC
- Generate
k = PBDKF2(p, s, i)
- Retrieve
iv
,a
andc
fromC
- Generate the plain text
p = AES_decrypt(k, c, iv, a)
Shared-key encryption is used to securely share sensitive data between a number of independent accessors without the need for them to share a common password. This encryption scheme is loosely based on the JSON Web Encryption specification where a shared symmetric encryption key is individually encrypted with each accessors public key and stored alongside the encrypted data. Accessors can then access the data by using their private key to decrypt the AES encryption key which is in turn used to decrypt the original data.
- Generate a random encryption key
k
- Choose a random initialization vector
iv
and additional dataa
(for authenticated encryption modes) - Generate the encrypted data
c = AES_encrypt(k, p, iv, a)
from the plain textp
- Let
[A_1, A_2, ..., A_n], A_n = { id_n, pub_n }
be a number of desired accessors wherepub_n
is the accessors public key andid_n
a unique identifier. - For each accessor, generate
K_n = RSA_encrypt(pub_n, k)
- Store
c
,iv
,a
, andK = [{ id_1, K_1}, ..., {id_n, K_n}]
in containerC
┏━━━━━━━━━━━━━━┓ ┌───────────────────────────────────────────────────────────┐
┃ Accessor A ┃ │ │
┃ ┃ ▼ ┏━━━━━━━━━━━━━━━━┓ │
┃┌ ─ ─ ─ ─ ─ ─ ┃ ┌─────────┐ ┃Shared Container┃ ============== │
┃ public key │─────┐ │ encrypt │ ┃ ┃ = plain text = │
┃└ ─ ─ ─ ─ ─ ─ ┃ └─────▶│ (RSA) │─────┐ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ ============== │
┃╔════════════╗┃ └─────────┘ │ ┃ encrypted │┃ │ │
┃║private key ║┃ └─────▶│ key (A) ┃ ▼ │
┃╚════════════╝┃ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ ┌─────────┐ │
┗━━━━━━━━━━━━━━┛ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ │ encrypt │ =========
┃ encrypted │┃ ┌───│ (AES) │◀────== key ==
┌─────▶│ key (B) ┃ │ └─────────┘ =========
│ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ │ │ │
┏━━━━━━━━━━━━━━┓ │ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ │ │ │
┃ Accessor B ┃ │ ┃ encryption │┃ │ │ │
┃ ┃ │ ┃│ parameters ◀─┘ │ │
┃┌ ─ ─ ─ ─ ─ ─ ┃ ┌─────────┐ │ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ │ │
┃ public key │─────┐ │ encrypt │ │ ┃╔══════════════╗┃ │ │
┃└ ─ ─ ─ ─ ─ ─ ┃ └─────▶│ (RSA) │─────┘ ┃║encrypted data║◀──────────┘ │
┃╔════════════╗┃ └─────────┘ ┃╚══════════════╝┃ │
┃║private key ║┃ ▲ ┗━━━━━━━━━━━━━━━━┛ │
┃╚════════════╝┃ │ │
┗━━━━━━━━━━━━━━┛ └───────────────────────────────────────────────────────────┘
- Let
id_n
,priv_n
be the id and private key of one of the accessors used during encryption. - Retrieve
K
fromC
, find the encrypted keyK_n
forid_n
. - Generate
k = RSA_decrypt(priv_n, K_n)
- Retrieve
iv
,a
andc
fromC
- Generate the plain text
p = AES_decrypt(k, c, iv, a)
┌─────────┐
┏━━━━━━━━━━━━━━┓ │ decrypt │ ┏━━━━━━━━━━━━━━━━┓
┃ Accessor A ┃ ┌─────────▶│ (RSA) │◀────────┐ ┃Shared Container┃
┃ ┃ │ └─────────┘ │ ┃ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │ │ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
┃ public key │┃ │ │ │ ┃ encrypted │┃
┃└ ─ ─ ─ ─ ─ ─ ┃ │ ========= │ └─────────│ key (A) ┃
┃╔════════════╗┃ │ == key ==◀─┘ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
┃║private key ║─────────┘ ========= ┌───────────┐ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
┃╚════════════╝┃ │ │ │ ┃ encryption │┃
┗━━━━━━━━━━━━━━┛ │ ▼ └──────│ parameters ┃
│ ┌─────────┐ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
│ │ decrypt │ ┃╔══════════════╗┃
└──────▶│ (AES) │◀────────────║encrypted data║┃
└─────────┘ ┃╚══════════════╝┃
│ ┗━━━━━━━━━━━━━━━━┛
▼
==============
= plain text =
==============
[[TODO]]
The Account object represents an individual Padloc user and is central to Padlocs encryption and authentication mechanisms. Each Account holds the following information:
- The user's email address is not only used as a communication channel but, more importantly, serves as a unique, human-verifiable identifier for each Padloc user.
- A RSA private key and public key pair is used in places where a user needs to be granted access to data protected via the Shared-Key Encryption Scheme.
- A HMAC key used for signing and verifing organization details (see Organizations And Shared Vaults / Adding Members
- A unique, immutable id
- A (display) name
The Accounts private key and organization signing key are considered secret and should only ever be accessible to the Account owner themselves. They are therefore encrypted at rest using the Password-Based Encryption Scheme with the users Master Password serving as the secret passphrase.
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ Account ┃ ╔═══════════╗
┃ ┃ ║ encrypted ║
┃ ┌ ─ ┐┌ ─ ─ ┐┌ ─ ─ ┐ ┃ ╚═══════════╝
┃ id name email ┃ ┌ ─ ─ ─ ─ ─ ┐
┃ └ ─ ┘└ ─ ─ ┘└ ─ ─ ┘ ┃ plain
=================== ┃ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┃ └ ─ ─ ─ ─ ─ ┘
= Master Password =───────┐ ┃ public key ┃ =============
=================== │ ┃ └ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ┃ = ephemeral =
│ ┃ ╔═════════════════╗ ┃ =============
decrypts ┃ ║ ┌─────────────┐ ║ ┃
│ ┃ ║ │ private key │ ║ ┃
│ ┃ ║ └─────────────┘ ║ ┃
└───────▶║ ┌─────────────┐ ║ ┃
┃ ║ │ signing key │ ║ ┃
┃ ║ └─────────────┘ ║ ┃
┃ ╚═════════════════╝ ┃
┗━━━━━━━━━━━━━━━━━━━━━┛
A password managers core functionality is the secure storage of sensitive data like passwords, credit card details and or any other kind or data a user may want to protect from prying eyes. In Padloc, this data is stored within so-called Vaults.
A Vault is basically a container object that employs the Shared-Key Encryption Scheme to encrypt and store sensitive data in a way that makes it accessible to only a number of specific users, represented by their corresponding Account objects.
┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓
┃ Account ┃ ┃ Vault ┃
┃ ┃ ┃ ┃
┃ ┌ ─ ─ ─ ─ ─ ┐ ┃ ┃ ╔══════════╗ ┃
┃ public key ──────encrypts──────▶║vault data║ ┃
┃ └ ─ ─ ─ ─ ─ ┘ ┃ ┃ ╚══════════╝ ┃
┃ ╔═══════════╗ ┃ ┃ ▲ ┃
┃ ║private key║──────decrypts─────────────┘ ┃
┃ ╚═══════════╝ ┃ ┃ ┃
┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━┛
Each Padloc user owns a private vault to which only they have access. In addition to this, Shared Vaults can be used to share sensitive data between multiple members within an Organization. For more details on this, see the Organizations And Shared Vaults section.
Shared Vaults can be used to securely share sensitive data between multiple users. These vaults are provisioned and managed as part of Organizations, which deal with permission management as well as public key and identity verification.
The previous sections describe how Vault data can be shared securely between multiple known accounts. An additional challenge lies in deciding who shall have access to a given vault as well as obtaining and verifying each accessors public key before encryption.
The organisation structure depicted below determines which member shall have access to a given vault. Members can either be assigned to a Vault directly or indirectly via a Group.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ │ ╱│ │╲ │ │
│ Account │┼─────────○─│ Membership │──┼────────┼│ Organization │
│ │ ╲│ │╱ │ │
└──────────────┘ └───┬──────┬───┘ └──────────────┘
╲│╱ ╲│╱ ┼
○ ○ ○
│ │ ╱│╲
│ │ ┌──────────────┐
│ │ ╱│ │
│ └──────────────○─│ Group │
│ ╲│ │
○ └──────────────┘
╱│╲ ╲│╱
┌──────────────┐ ○
│ │╲ │
│ Shared Vault │─○──────────────────────┘
│ │╱
└──────────────┘
Every time a Vault participant encrypts the vault data, they perform the following steps:
- Determine accessors based on organization structure.
- Verify each accessor's identity and public key (see Verifying Members)
- Encrypt the data using the steps outlined in Shared-Key Encryption
Each participating member can now access the Vault data using their own private key.
In addition to Group and Member data, Organizations also hold the following information:
- The organization id is a random, unique identier assigned to it by the server
- The organization name is chosen by the organization owner and is mainly used for display purposes
- A RSA public key and private key pair that is used to sign and verify public keys and identifying information of its members. See Signing Member Information and Verifying Members for details.
- An AES key (in the following called "invites key") used to encrypt the invite verification code during key exchange
The organization's private key and invites key are considered secret and need therefore be encrypted at rest. For this, the organization acts as a Shared Crypto Container with the organization owners acting as accessors.
┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━┓
┃ Organization ┃ ┃ Organization ┃
┃ Owner ┃ ┃ ┃
┃ ┃ ┃ ╔═══════════════╗ ┃
┃ ┌ ─ ─ ─ ─ ─ ┐ ┃ ┃ ║┌─────────────┐║ ┃
┃ public key ──────encrypts──────▶║│ private key │║ ┃
┃ └ ─ ─ ─ ─ ─ ┘ ┃ ┃ ║└─────────────┘║ ┃
┃ ╔═══════════╗ ┃ ┃ ║┌─────────────┐║ ┃
┃ ║private key║──────decrypts──────▶║│ invites key │║ ┃
┃ ╚═══════════╝ ┃ ┃ ║└─────────────┘║ ┃
┗━━━━━━━━━━━━━━━┛ ┃ ╚═══════════════╝ ┃
┗━━━━━━━━━━━━━━━━━━━━┛
As with all cryptographic schemes that involve public-key encryption, a major challenge when dealing with shared vaults is securely exchanging and verifying the public keys and associated identities of all involved parties. This undertaking is complicated further by the fact that, although all communication and data transfer is generally mediated by a central server, Padlocs Zero-Trust Principle requires that this server (or any party potentially listening in on the connection) is never in the position to directly access any sensitive data or trick a participant into granting them access either directly or indirectly.
Instead of exchanging keys between all organization members directly, Padloc uses a simple verification chain where the public keys and identfying information of all members are signed and verified with a dedicated RSA key pair owned by the organization (see Metadata and Cryptographic Keys). The corresponding public key must in turn be signed and verified by each member using their individual, dedicated HMAC key.
Before a new member can be added to an Organization, a key exchange has to take place between the organization (represented by the organization owner) and the new member. The key exchange is performed as follows:
- The organization owner
O
chooses a random passphrasep
, a random salts
and an iteration counti
as well as a random, unique exchange id. p
,s
andi
are used to generate the HMAC keyx = PBKDF2(p, s, i)
.O
signs the organizations public keypub_o
withx
:sig_o = HMAC(x, pub_o)
O
sendss
,i
,pub_o
andsig_o
to the serverS
, along with the exchange id and the recipients email address.- The server stores the received values and sends the invitation link (which
includes the exchange id) to
I
via email. I
uses the exchange id to requests
,i
,pub_o
andsig_o
fromS
.I
requestsp
fromO
via a separate (and optimally secure) channel of their choice. This can be in person, via phone or any by other means.I
generatesx = PBKDF2(p, s, i)
using the obtained information.I
verifiespub_o
usingx
andsig_o
.- Upon successful verification,
I
signs their own public keypub_i
usingx
:sig_i = HMAC(x, pub_i)
I
sendspub_i
andsig_i
toS
, which forwards them toO
.O
verifiespub_i
usingsig_i
andx
.
┌─────────────┐ ┌──────────┐ ┌───────────┐
│Org Owner (O)│ │Server (S)│ │Invitee (I)│
└──────┬──────┘ └────┬─────┘ └─────┬─────┘
┌─────────────────────┐ │ │ │
│p = [passphrase] │ │ s, i, id, email, │ │
│s = [random salt] │ │ pub_o, sig_o │ id (via email) │
│i = [iteration count]│ │─────────────────▶│─────────────────▷│
│x = PBKDF2(p,s,i) │ │ │ │
│pub_o = [public key] │ │ │ id │
│sig_o = HMAC(x,pub_o)│ │ │◀─────────────────│
│id = [invite id] │ │ │ s, i, │
│email = [inv. email] │ │ │ pub_o, sig_o │
└─────────────────────┘ │ │─ ─ ─ ─ ─ ─ ─ ─ ─▶│
│ │ │
│ │ p (in person) │ ┌─────────────────────┐
│────────────────────────────────────▷│ │pub_i = [public key] │
│ │ │ │x = PBKDF2(p,s,i) │
┌─────────────────┐ │ pub_i, sig_i │ pub_i, sig_i │ │x => verify sig_o │
│x => verify sig_i│ │◀─────────────────│◀─────────────────│ │sig_i = HMAC(x,pub_i)│
└─────────────────┘ │ │ │ └─────────────────────┘
│ │ │
│ │ │
│ │ │
▼ ▼ ▼
-
In practice, the member's account id and email and the organization id are included in the respective signatures to protect these from tempering as well.
-
Since
p
needs to be sufficiently short to be conveniently entered by hand, it can potentially be guessed by eavesdroppers which would allow them to successfully perform a man-in-the-middle attack by injecting their own public key. This is mitigated by using a sufficiently large iteration counti
and invalidating key exchanges after a certain amount of time. -
Using a separate, direct communication channel for communicating the secret passphrase not only mitigates the risk of man-in-the-middle attacks but also means that the server
S
does not need to be explicitly trusted. Furthermore, the risk of phishing attacks by a third party (including a malicious server admin) is greatly reduced since a direct, personal interaction between the parties is required. -
Since some time may pass between steps 1. and 7.,
p
needs to be stored securely for later reference. This is done by encrypting it with a dedicated AES "invites key" which is only accessible to organization owners. (See Metadata and Cryptographic Keys.
Once the new member and organization have successfully exchanged public keys, these need to be stored in a way that allows both parties to be verify them later. The invitees public key (along with their identifying information) is signed by the organizations private key (only available to the organization owner) while the organizations public key is signed by the invitees own, dedicated HMAC key.
┏━━━━━━━━━━━━━━┓
┃Member Account┃
┃ ┃ ┌────────┐
┃╔════════════╗┃ │ sign │
┃║signing key ║──────────▶│ (HMAC) │◀────┐
┃╚════════════╝┃ └────────┘ │
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │
┃ public key │─────────────┐ │ │
┃└ ─ ─ ─ ─ ─ ─ ┃ │ │ │
┗━━━━━━━━━━━━━━┛ │ │ │
│ │ │ ┏━━━━━━━━━━━━━━┓
┏━━━━━━━━━━━━━━┓ │ │ │ ┃ Organization ┃
┃ Membership ┃ │ │ │ ┃ ┃
┃ ┃ │ │ │ ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │ └───── public key │┃
┃ organization│┃ │ │ ┃└ ─ ─ ─ ─ ─ ─ ┃
┃│ signature ◀────────────│──┘ ┃╔════════════╗┃
┃ ─ ─ ─ ─ ─ ─ ┘┃ ▼ ┌─────║private key ║┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ ┌────────┐ │ ┃╚════════════╝┃
┃ member │┃ │ sign │ │ ┗━━━━━━━━━━━━━━┛
┃│ signature ◀──────────│ (RSA) │◀────┘
┃ ─ ─ ─ ─ ─ ─ ┘┃ └────────┘
┗━━━━━━━━━━━━━━┛
Using the signatures described in the previous section, an organization member can verify the public key of any other member as follows.
- Verify the organizations public key using the organization signature created with their own HMAC key
- Verify the other member's public key using the organization's public key.
┏━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓
┃ Account A ┃ ┃ Org ┃ ┃ Account B ┃
┃ ┃ ┌────────┐ ┃ ┃ ┌────────┐ ┃ ┃
┃╔════════════╗┃ │ verify │ ┃┌ ─ ─ ─ ─ ─ ─ ┃ │ verify │ ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃║signing key ║────▶│ (HMAC) │◀──── public key │────▶│ (RSA) │◀─── public key │┃
┃╚════════════╝┃ └────────┘ ┃└ ─ ─ ─ ─ ─ ─ ┃ └────────┘ ┃└ ─ ─ ─ ─ ─ ─ ┃
┗━━━━━━━━━━━━━━┛ ▲ ┃╔════════════╗┃ ▲ ┗━━━━━━━━━━━━━━┛
│ ┃║private key ║┃ │ ┏━━━━━━━━━━━━━━┓
┏━━━━━━━━━━━━━━┓ │ ┃╚════════════╝┃ │ ┃ Membership B ┃
┃ Membership A ┃ │ ┗━━━━━━━━━━━━━━┛ │ ┃ ┃
┃ ┃ │ │ ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │ ┃ member │┃
┃ organization│┃ │ └────────│ signature ┃
┃│ signature ┣─────────┘ ┃ ─ ─ ─ ─ ─ ─ ┘┃
┃ ─ ─ ─ ─ ─ ─ ┘┃ ┗━━━━━━━━━━━━━━┛
┗━━━━━━━━━━━━━━┛
There are three distinct organization roles: Owner, Admin and basic Member. Each role comes with a different set of privileges. Some privileges are enforced cryptographically while others are enforced solely by the server.
A basic organization member has the following privileges.
- Read the public data of other members, including id, email, public key and assigned vaults and groups.
- Read vault data of assigned vaults
- Update vault data of assigned vaults where write permissions have been granted explicitly
All of these privileges are enforced by the server (e.g. a vaults encrypted data will only be provided to a member if they are assigned to that vault) while access to the plain text data stored in vaults is also restricted cryptographically through the encryption mechanism described in Vaults.
In addition to the privileges granted to basic members, admins also have the following privileges:
- Create and delete Vaults
- Assign vault access to groups and members directly
- Create, delete and manage groups
In addition to the privileges granted to basic members and admins, organization owners also have the following privileges:
- Add/remove organization members
- Update a members id, email, public key or role
- Update the organizations public/private key pair
As described in a previous section, adding a new member to the organization requires access to the organizations private key. As described in Metadata and Cryptographic Keys, this access is restricted cryptographically to organization owners.
Even though all sensitive information in padloc is end-to-end encrypted and theoretically secure even in case of an insecure connection or even a compromised server, padloc still uses a robust authentication scheme to limit access to user data, ensure payload integrity and enforce user permissions. A variation of the Secure Remote Password protocol is used to authenticate users and establish a secure connection between client and server without exposing the user's master password.
Whenever a user creates a Padloc account, the following steps take place:
- Let
u
andp
be the user's email address and master password, respectively. - The client
C
sendsu
to the serverS
. - The server sends an email verification code
c
to the user's email address. C
chooses a random salts
and iteration counti
C
generatesx = PBKDF2(p, s, i)
and the password verifierv = v(x)
*C
sendsu
,v
,s
,i
andc
toS
S
verifiesc
and, if successful, storesu
,v
,s
andi
for later use.
The signup process is now complete and the stored values can be used to verify the users identity and to negotiate a common session key.
┌──────────┐ ┌──────────┐
│Client (C)│ │Server (S)│
└─────┬────┘ └────┬─────┘
┌───────────────────┐ │ │
│u = [email address]│ │ u │
└───────────────────┘ │──────────────▶│ ┌───────────────────────┐
│ │ │c = [verification code]│
│ │ └───────────────────────┘
┌─────────────────────┐ │ c (via email) │
│p = [master password]│ │◁ ─ ─ ─ ─ ─ ─ ─│
│s = [random salt] │ │ │
│i = [iteration count]│ │ │
│x = PBKDF2(p,s,i) │ │ u, v, s, i, c │ ┌───────────────────┐
│v = v(x)* │ │──────────────▶│ │=> verify c │
└─────────────────────┘ │ │ │=> store u, v, s, i│
│ │ └───────────────────┘
│ │
▼ ▼
In order to "log into" an existing account, a common session key needs to be negotiated. This happens as follows:
- Let
u
andp
be the users email address and master password, respectively. - The client
C
generates the random valuesa
andA
* C
sendsu
andA
to the ServerS
.S
looks ups
andi
based onu
and generates the random valuesb
andB
*.S
sendss
,i
andB
toC
.C
generatesx = PBKDF2(p, s, i)
,K = K_client(x, a, B)
andM = M(A, B, K)
*.C
sendsM
toS
.S
generates its ownK' = K_server(v, b, A)
andM' = M(A, B, K')
*.S
verifies thatM == M'
and thereforeK == K'
. If verification fails, the session negotiation is aborted.- If successful,
S
storesK
under the session idsid
. S
sendssid
toC
, which also stores it along withK
for later use.
Client and server now have a common and secret session key K
which
can be used for authenticating subsequent requests.
┌──────────┐ ┌──────────┐
│Client (C)│ │Server (S)│
└─────┬────┘ └────┬─────┘
┌───────────────────┐ │ │
│u = [email address]│ │ u, A │
│a, A = [random*] │ │──────────────▶│
└───────────────────┘ │ │ ┌────────────────┐
│ │ │b, B = [random*]│
┌───────────────────────┐ │ s, i, B │ └────────────────┘
│p = [master password] │ │◁ ─ ─ ─ ─ ─ ─ ─│
│x = PBKDF2(p,s,i) │ │ │
│K = K_client(x, a, B)* │ │ │
│M = M(A, B, K)* │ │ M │ ┌───────────────────────┐
└───────────────────────┘ │──────────────▶│ │K' = K_server(v, b, A)*│
│ │ │M' = M(A, B, K') │
│ │ │=> verify M == M' │
┌───────────────┐ │ sid │ │S = [session id] │
│=> store sid, K│ │◀ ─ ─ ─ ─ ─ ─ ─│ │=> store sid, K │
└───────────────┘ │ │ └───────────────────────┘
│ │
▼ ▼
Using the common session key K
Client and Server can now authenticate
each request as follows:
- Let
sid
andK
be the previously negotiated session id and key. - Let
req
be the intended request body andt1
the time stamp at the time of the request. C
generates the signaturesig1 = HMAC(K, sid|t1|req)
.C
sendsreq
,sid
,t1
andsig1
toS
.S
verifiesreq
,sid
andt1
usingsig1
. If verification fails, or ift1
is older than a predetermined maximum request age, the request is rejected.- Let
res
be the response body andt2
the time stamp at the time of the response. S
generatessig2 = HMAC(K, sid|t2|res)
.S
sendsres
,t2
andsig2
toC
.C
verifiesres
,sid
andt2
usingsig2
. If verification fails, or ift2
is older than a predetermined maximum response age, the response is rejected.
┌──────────┐ ┌──────────┐
│Client (C)│ │Server (S)│
└─────┬────┘ └────┬─────┘
┌──────────────────────────┐ │ │
│req = [request body] │ │ req, sid, │
│t1 = [timestamp] │ │ t1, sig1 │ ┌──────────────────────────┐
│sig1 = HMAC(K, sid|t1|req)│ │──────────────▶│ │=> verify sig1 │
└──────────────────────────┘ │ │ │res = [response body] │
│ │ │t2 = [timestamp] │
┌──────────────┐ │ res, t2, sig2 │ │sig2 = HMAC(K, sid|t2|res)│
│=> verify sig2│ │◁ ─ ─ ─ ─ ─ ─ ─│ └──────────────────────────┘
└──────────────┘ │ │
│ │
▼ ▼
* For details on how v
, a
, A
, b
, B
, K
and M
are generated, refer to the SRP
specification
- Even though
v
is based onp
, it can not be used to guess the password in case someone eavesdrops on the connection or if the server is compromised. See section 4 of the SRP specification for details. - The session key
K
cannot be sniffed out since it is never transmitted. It could theoretically be guessed from the request signature but with a key size of 256 bits this is not really feasible either. - The salt and iteration count used for generating
x
as well as the resulting authentication key are completely independent of the corresponding values used for encrypting the accounts private key, even though the derivation scheme and base passphrase are the same. - Request authentication works both ways. Not only can the server verify the users identity and knowledge of their master password, the client can also verify the identity of the server.
- The described authentication mechanism not only allows for identity verification, but also prevents tempering with the request/response body or timestamp.
- Rejecting request and responses older than a certain age mitigates the risk of replay attacks.
This section covers various possible attack vectors and mitigation steps taken.
A man-in-the-middle attack is an attack where the attacker secretly relays the communication between two parties in order to eavesdrop on the connection and/or temper with messages in transit.
MITM attacks may be launched in a multitude of ways, and even with technlogies like TLS, it is very hard to completely rule out that other parties may be listening in on the connection or even trying to tamper with the messages exchanged. Therefore, steps should be taken not only to mitigate the risk of a successful MITM attack, but also to ensure that even in case of an insecure connection, an attacker may never get access to any sensitive information or compromise the security of the application in any other way.
- Communication between the Padloc client and server is always secured through Transport Layer Security.
- No sensitive information is ever transmitted in plain text.
- Transmitted data is protected from tampering through Padloc's strong Authentication Mechanism.
- Padloc's Key Exchange Mechanism is designed to be secure even over an untrusted connection.
With the addition of Organizations And Shared Vaults in Padloc 3, phishing has become a potential attack vector as well. Attackers may try to lure Padloc users into sharing sensitive information by inviting them to misleadingly named organizations which can be mistaken for an employer or friend. Users could then accidentally share data within vaults assigned to them.
However, the procedure for inviting and adding a new member to an organization is designed in a way that makes this very hard to accomplish, since it requires direct, personal coordination between both parties. See Trustless Server-Mediated Key Exchange for more details.
Padloc uses a combination of various strong encryption algorithms to protect all sensitive data and cryptographic keys both at rest and during transmission. The master password acts as a universal key for this encryption scheme.
Master passwords are never stored anywhere and should only ever be known by the Padloc user themself. Unfortunately, since this means that in the majority of use cases the user will have to commit this password to memory, the "key space" of feasible passwords is relatively limited. Additionally, since master passwords are ultimately chosen by the user, no guarantee can be made to the strength or randomness of these passwords.
This means that master password are a prime-target for guessing attacks of all sorts and steps should be taken to make these attacks either infeasible or, at a very minimum, too costly to be worthwhile.
[[TODO]]
[[TODO]]
[[TODO]]
[[TODO]]
[[TODO]]
For all symmetric encryption operations, the AES Cipher is used in GCM mode with a key size of 256 bits.
Areas of use:
For asymmetric encryption operations, the RSA-OAEP algorithm is used with a modulus length of 2048 bits and the SHA-256 hash function.
Areas of use:
For symmetric signature creation and verification, the HMAC algorithm is used with a key length of 256 bits and the SHA-256 hash function.
Areas of use:
For asymmetric signature creation and verification, the RSA-PSS algorithm is used with a modulus length of 2048 bits, a salt length of 256 bits and the SHA-256 hash function.
Areas of use:
For password-based key derivation, the PBKDF2 algorithm is used with the SHA-256 hash function and a salt length of 128 bits. The iteration count varies by area of use.
Areas of use: