mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-11 17:42:07 +00:00
Update vault documentation
Here some changes to the vault documentation are made. The documentation is updated to reflect the latest versions of both the vault and the database, i.e. vault version 1 and database version 3. Co-authored-by: Alexander Bakker <ab@alexbakker.me>
This commit is contained in:
parent
224ec2553c
commit
f91b6f0466
1 changed files with 177 additions and 58 deletions
235
docs/vault.md
235
docs/vault.md
|
@ -14,8 +14,10 @@ format of the vault.
|
|||
### Primitives
|
||||
|
||||
Two cryptographic primitives were selected for use in Aegis. An Authenticated
|
||||
Encryption with Associated Data (AEAD) cipher and a Key Derivation Function
|
||||
(KDF).
|
||||
Encryption with Associated Data
|
||||
([AEAD](https://en.wikipedia.org/wiki/Authenticated_encryption#Authenticated_encryption_with_associated_data))
|
||||
cipher and a Key Derivation Function
|
||||
([KDF](https://en.wikipedia.org/wiki/Key_derivation_function)).
|
||||
|
||||
#### AEAD
|
||||
|
||||
|
@ -36,15 +38,16 @@ This is a reasonable assumption to make, because it's highly unlikely that an
|
|||
Aegis user will ever come close to saving the vault 2<sup>32</sup> times.
|
||||
|
||||
_Switching to a nonce misuse-resistant cipher like AES-GCM-SIV or a cipher with
|
||||
a larger (192 bits) nonce like XChaCha-Poly1305 will be considered in the future._
|
||||
a larger (192 bits) nonce like XChaCha-Poly1305 will be considered in the
|
||||
future._
|
||||
|
||||
#### KDF
|
||||
|
||||
__scrypt__ is used as the KDF to derive a key from a user-provided password,
|
||||
with the following parameters:
|
||||
[__scrypt__](https://en.wikipedia.org/wiki/Scrypt) is used as the KDF to derive
|
||||
a key from a user-provided password, with the following parameters:
|
||||
|
||||
| Parameter | Value |
|
||||
| :-------- | :------------- |
|
||||
| Parameter | Value |
|
||||
|:----------|:---------------|
|
||||
| N | 2<sup>15</sup> |
|
||||
| r | 8 |
|
||||
| p | 1 |
|
||||
|
@ -104,12 +107,17 @@ shown below:
|
|||
}
|
||||
```
|
||||
|
||||
It starts with a ``version`` number and a ``header``. If a backwards
|
||||
incompatible change is introduced to the content format, the version number will
|
||||
be incremented. The vault contents are stored under ``db``. Its value depends on
|
||||
whether the vault is encrypted or not. If it is, the value is a string containing
|
||||
the Base64 encoded (with padding) ciphertext of the vault contents. Otherwise,
|
||||
the value is a JSON object.
|
||||
It starts with a ``version`` number. If a forwards incompatible change is
|
||||
introduced to the vault format, the version number will be incremented. The
|
||||
current version of the vault format is ``1``.
|
||||
|
||||
The [``header``](#header), if not empty, contains the list of slots and the
|
||||
encryption parameters used for decrypting the vault.
|
||||
|
||||
The vault contents are stored under ``db``. Its value depends on whether the
|
||||
vault is encrypted or not. If it is, the value is a string containing the Base64
|
||||
encoded (with padding) ciphertext of the vault contents. Otherwise, the value is
|
||||
a JSON object. See [vault content](#vault-content) for details.
|
||||
|
||||
Full examples of a [plain text
|
||||
vault](/app/src/test/resources/com/beemdevelopment/aegis/importers/aegis_plain.json)
|
||||
|
@ -122,9 +130,14 @@ password: [decrypt.py](/docs/decrypt.py).
|
|||
|
||||
### Header
|
||||
|
||||
The header starts with the list of ``slots``. It also has a ``params`` object
|
||||
that holds the ``nonce`` and ``tag`` that were produced during encryption,
|
||||
encoded as a hexadecimal string.
|
||||
The header starts with the list of [``slots``](#slots-1). Each slot contains the
|
||||
master key in an encrypted form together with the key wrapping parameters.
|
||||
|
||||
It also has a ``params`` object that holds the ``nonce`` and ``tag`` that were
|
||||
produced during the AES-GCM encryption, encoded as a hexadecimal string. These
|
||||
encryption parameters together with the master key (which can be retrieved by
|
||||
decrypting the ``key`` from one of the slots) are used to decrypt the vault
|
||||
contents found in the ``db`` field.
|
||||
|
||||
Setting ``slots`` and ``params`` to null indicates that the vault is not
|
||||
encrypted and Aegis will try to parse it as such.
|
||||
|
@ -141,13 +154,13 @@ encrypted and Aegis will try to parse it as such.
|
|||
|
||||
#### Slots
|
||||
|
||||
The different slot types are identified with a numerical ID.
|
||||
The different slot types are identified with a numerical ID.
|
||||
|
||||
| Type | ID |
|
||||
| :---------- | :--- |
|
||||
| Raw | 0x00 |
|
||||
| Password | 0x01 |
|
||||
| Biometric | 0x02 |
|
||||
| Type | ID |
|
||||
|:----------|:-----|
|
||||
| Raw | 0x00 |
|
||||
| Password | 0x01 |
|
||||
| Biometric | 0x02 |
|
||||
|
||||
##### Raw
|
||||
|
||||
|
@ -182,7 +195,7 @@ Raw slots don't imply use of a particular storage type.
|
|||
|
||||
As noted earlier, scrypt is used to derive a 256-bit key from a user-provided
|
||||
password. A random 256-bit ``salt`` is generated and passed to scrypt to protect
|
||||
against rainbow table attacks. Its stored along with the ``N``, ``r`` and ``p``
|
||||
against rainbow table attacks. It's stored along with the ``N``, ``r`` and ``p``
|
||||
parameters.
|
||||
|
||||
```json
|
||||
|
@ -201,56 +214,69 @@ parameters.
|
|||
}
|
||||
```
|
||||
|
||||
### Content
|
||||
### Vault content
|
||||
|
||||
The content is a JSON object encoded in UTF-8.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"entries": []
|
||||
"version": 3,
|
||||
"entries": [],
|
||||
"groups": []
|
||||
}
|
||||
```
|
||||
|
||||
It has a ``version`` number and a list of ``entries``. If a backwards
|
||||
incompatible change is introduced to the content format, the version number will
|
||||
be incremented.
|
||||
It has a ``version`` number, a list of ``entries`` and a list of ``groups``. If
|
||||
a forwards incompatible change is introduced to the content format, the version
|
||||
number will be incremented. The current version of the vault content format is
|
||||
``3``.
|
||||
|
||||
| Field | Type | Description |
|
||||
|:------------|:------|:-----------------------------------------|
|
||||
| ``version`` | int | The version of the vault content format. |
|
||||
| ``entries`` | array | A list of [entries](#entries). |
|
||||
| ``groups`` | array | A list of [groups](#groups). |
|
||||
|
||||
#### Entries
|
||||
|
||||
Each entry has a unique randomly generated ``UUID`` (version 4), as well as a
|
||||
``name`` and ``issuer`` to identify the account name and service that the token
|
||||
is for. Entries can also have an icon. These are JPEG's encoded in Base64 with
|
||||
padding. The ``info`` object holds information specific to the OTP type. The
|
||||
``secret`` is encoded in Base32 without padding.
|
||||
Each entry has a unique randomly generated ``UUID``, as well as a ``name`` and
|
||||
``issuer`` to identify the account name and service that the token is for.
|
||||
|
||||
Entries hold the following fields:
|
||||
|
||||
| Field | Type | Description |
|
||||
|:--------------|:---------------|:--------------------------------------------------------------------------------|
|
||||
| ``type`` | string | The type of the OTP algorithm. See table below. |
|
||||
| ``uuid`` | string | A UUID (version 4). |
|
||||
| ``name`` | string | The account name. |
|
||||
| ``issuer`` | string | The service that the token is for. |
|
||||
| ``note`` | string | A personal note about the entry. |
|
||||
| ``icon`` | string \| null | JPEG's encoded in Base64 with padding. |
|
||||
| ``icon_mime`` | string \| null | The MIME type of the icon. Is null if ``icon`` is null. |
|
||||
| ``icon_hash`` | string \| null | The SHA-256 hash of the icon. Is null if ``icon`` is null. |
|
||||
| ``favorite`` | bool | Whether the entry is a favorite or not. |
|
||||
| ``info`` | object | Information specific to the OTP type. |
|
||||
| ``groups`` | array | A list of UUIDs of groups that the entry is a member of. See [Groups](#groups). |
|
||||
|
||||
The ``info`` object contains different fields depending on the type of the OTP.
|
||||
|
||||
There are a number of supported types:
|
||||
|
||||
| Type | ID | Spec |
|
||||
| :------------------ | :------- | :-------- |
|
||||
| HOTP | "hotp" | [RFC 4226](https://datatracker.ietf.org/doc/html/rfc4226)
|
||||
| TOTP | "totp" | [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238)
|
||||
| Steam | "steam" | N/A
|
||||
| Yandex | "yandex" | N/A
|
||||
| Type | ID | Spec |
|
||||
|:-------|:---------|:----------------------------------------------------------|
|
||||
| HOTP | "hotp" | [RFC 4226](https://datatracker.ietf.org/doc/html/rfc4226) |
|
||||
| TOTP | "totp" | [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238) |
|
||||
| Steam | "steam" | N/A |
|
||||
| MOTP | "motp" | N/A |
|
||||
| Yandex | "yandex" | N/A |
|
||||
|
||||
There is no specification available for Steam's OTP algorithm. It's essentially
|
||||
the same as TOTP, but it uses a different final encoding step. Aegis'
|
||||
implementation of it can be found in
|
||||
[crypto/otp/OTP.java](https://github.com/beemdevelopment/Aegis/blob/master/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java).
|
||||
Common ``info`` fields for all types:
|
||||
|
||||
There is also no specification available for Yandex's OTP algorithm. Aegis'
|
||||
implementation can be found in
|
||||
[crypto/otp/YAOTP.java](https://github.com/beemdevelopment/Aegis/blob/master/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/YAOTP.java)
|
||||
|
||||
The following algorithms are supported for HOTP and TOTP:
|
||||
|
||||
| Algorithm | ID |
|
||||
| :-------- | :------- |
|
||||
| SHA-1 | "SHA1" |
|
||||
| SHA-256 | "SHA256" |
|
||||
| SHA-512 | "SHA512" |
|
||||
|
||||
For Steam, only SHA-1 is supported. For Yandex, only SHA-256 is supported.
|
||||
| Field | Type | Description |
|
||||
|:-----------|:-------|:-----------------------------------|
|
||||
| ``secret`` | string | The Base32 encoded secret. |
|
||||
| ``algo`` | string | The hashing algorithm. |
|
||||
| ``digits`` | int | The number of digits in the token. |
|
||||
|
||||
Example of a TOTP entry:
|
||||
|
||||
|
@ -260,12 +286,105 @@ Example of a TOTP entry:
|
|||
"uuid": "01234567-89ab-cdef-0123-456789abcdef",
|
||||
"name": "Bob",
|
||||
"issuer": "Google",
|
||||
"note": "Main account",
|
||||
"favorite": false,
|
||||
"icon": null,
|
||||
"icon_mime": null,
|
||||
"icon_hash": null,
|
||||
"info": {
|
||||
"secret": "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
|
||||
"algo": "SHA1",
|
||||
"digits": 6,
|
||||
"period": 30
|
||||
}
|
||||
},
|
||||
"groups": [
|
||||
"01234567-89ab-cdef-0123-456789abcdef"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
##### HOTP and TOTP
|
||||
|
||||
TOTP uses the ``period`` field, which is the time step in seconds. HOTP uses the
|
||||
``counter`` field, which is incremented every time a token is generated.
|
||||
|
||||
The following algorithms are supported for HOTP and TOTP:
|
||||
|
||||
| Algorithm | ID |
|
||||
|:----------|:---------|
|
||||
| SHA-1 | "SHA1" |
|
||||
| SHA-256 | "SHA256" |
|
||||
| SHA-512 | "SHA512" |
|
||||
|
||||
##### Steam
|
||||
|
||||
There is no specification available for Steam's OTP algorithm. It's essentially
|
||||
the same as TOTP, but it uses a different final encoding step. Aegis'
|
||||
implementation of it can be found in
|
||||
[crypto/otp/OTP.java](/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java).
|
||||
|
||||
A couple of fields have fixed values:
|
||||
|
||||
| Field | Value |
|
||||
|:-----------|:-------|
|
||||
| ``algo`` | "SHA1" |
|
||||
| ``period`` | 30 |
|
||||
| ``digits`` | 5 |
|
||||
|
||||
##### MOTP
|
||||
|
||||
There is no specification available for MOTP. Aegis' implementation of it can be
|
||||
found in
|
||||
[crypto/otp/MOTP.java](/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/MOTP.java).
|
||||
|
||||
A couple of fields have fixed values:
|
||||
|
||||
| Field | Value |
|
||||
|:-----------|:------|
|
||||
| ``algo`` | "MD5" |
|
||||
| ``period`` | 10 |
|
||||
| ``digits`` | 6 |
|
||||
|
||||
MOTP-specific fields:
|
||||
|
||||
| Field | Type | Description |
|
||||
|:--------|:-------|:------------|
|
||||
| ``pin`` | string | 4-digit PIN |
|
||||
|
||||
##### Yandex
|
||||
|
||||
There is no specification available for Yandex's OTP algorithm. Aegis'
|
||||
implementation can be found in
|
||||
[crypto/otp/YAOTP.java](/app/src/main/java/com/beemdevelopment/aegis/crypto/otp/YAOTP.java)
|
||||
|
||||
A couple of fields have fixed values:
|
||||
|
||||
| Field | Value |
|
||||
|:-----------|:---------|
|
||||
| ``algo`` | "SHA256" |
|
||||
| ``period`` | 30 |
|
||||
| ``digits`` | 8 |
|
||||
|
||||
Yandex-specific fields:
|
||||
|
||||
| Field | Type | Description |
|
||||
|:--------|:-------|:---------------|
|
||||
| ``pin`` | string | 4-16 digit PIN |
|
||||
|
||||
#### Groups
|
||||
|
||||
A group consists of a ``name`` and a randomly generated ``uuid`` (version 4).
|
||||
|
||||
| Field | Type | Description |
|
||||
|:---------|:-------|:-----------------------|
|
||||
| ``uuid`` | string | A UUID (version 4). |
|
||||
| ``name`` | string | The name of the group. |
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"uuid": "01234567-89ab-cdef-0123-456789abcdef",
|
||||
"name": "Personal"
|
||||
}
|
||||
```
|
||||
|
|
Loading…
Add table
Reference in a new issue