Device
A Device always belongs to a user and is used to make sure the user can access their data from multiple devices.
Why not have a single Device per user?
The main reason is to allow the user to invalidate a Device without invalidating their entire account. This is useful if a device e.g. a mobile phone is lost or stolen.
Other reasons:
- There is no access to Secure Element on the web and in order to allow users still access through a web-interface, a Device is created for them and stored in the browser's localstorage and has an expiration date.
- Devices also reduce the risk of a user to completely loose their data e.g. when they lose their password.
Unfortionatly this decision also comes with some downsides:
- Need to encrypt for multiple device
- Need to manage the authenticity of multiple devices
MainDevice
The MainDevice
is only held in memory when decrypted and never stored in any kind of local storage regardless if it is a Web, mobile or desktop client.
Structure of a Device
A Device
consists of a:
- Signature Key Pair
- Encryption Key Pair
- Signature of the Encryption Public Key with the Signature Private Key
The purpose of the signature is to verify that
Code references:
- https://github.com/SerenityNotes/Serenity/blob/main/packages/common/src/createDevice/createDevice.ts (opens in a new tab)
- https://github.com/serenity-kit/Serenity/blob/main/packages/user-chain/src/verifyDevice.ts (opens in a new tab) (for user devices)
- https://github.com/serenity-kit/Serenity/blob/main/packages/document-chain/src/verifyDevice.ts (opens in a new tab) (for document share link devices)
Signature Key Pair
For the signature key pair, we use the Ed25519
algorithm which is generated using Libsodium's crypto_sign_keypair()
.
Encryption Key Pair
For the encryption key pair, we use the X25519
algorithm which is generated using Libsodium's crypto_box_keypair()
. The public key is then signed with the signature key pair using Libsodium's crypto_sign_detached()
.