Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write and update documentation for Account Recovery and ODIS #150

Merged
merged 51 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4162ffa
update stale yarn.lock file
Oct 15, 2021
89e254f
lay out the structure to fill in
Oct 15, 2021
6d22bf4
add basic descriptions of what should go in each page
Oct 15, 2021
a167581
update identity overview as I was reading through it
Oct 15, 2021
4dde6e6
update inforamtion about ODIS and the phone number privacy use case
Oct 18, 2021
69e65f3
move description of ODIS into the odis/index.md file
Oct 18, 2021
5bbbfa6
progress on updating the overview of ODIS
Oct 19, 2021
dc918c3
add new pages to the sidebar
Oct 19, 2021
c0a764e
finish updating the overview of ODIS
Oct 19, 2021
959f0c4
remove placeholder
Oct 19, 2021
ea46588
fix import of the PageRef component
Oct 19, 2021
f065b48
add information about domains
Oct 21, 2021
ab086e6
move valora-accounts to smart-contract-accounts
Oct 21, 2021
a08bbc9
update and expand the smart contract accounts page
Oct 21, 2021
b648e8f
add information about using ODIS for key hardening
Oct 21, 2021
3fd2abc
add information from the encrypted cloud backup summary page
Oct 21, 2021
4be783e
sentance wrap the identity/phone-number-privacy.md page
Oct 21, 2021
05e6d14
create an odis/use-cases forlder and link the phone number privacy ca…
Oct 21, 2021
25d1d11
Merge branch 'main' of github.com:celo-org/docs into victor/account-r…
Oct 21, 2021
480c283
adjust TODO comments
Oct 21, 2021
2d87512
fix broken links
critesjosh Oct 22, 2021
2547e45
fix broken links
critesjosh Oct 22, 2021
c0ee06b
fix broken links
critesjosh Oct 22, 2021
ec652e9
update broken link
critesjosh Oct 22, 2021
d080c0b
fix broken link
critesjosh Oct 22, 2021
9ca7fdc
Merge branch 'main' of github.com:celo-org/docs into victor/account-r…
Oct 22, 2021
5ebc01c
Merge branch 'victor/account-recovery-docs' of github.com:celo-org/do…
Oct 22, 2021
8b5c261
move phone-number-privacy docs
Oct 22, 2021
7a650cd
move phone-number-privacy to be a use-case of ODIS
Oct 22, 2021
d9d8577
remove vestigial SUMMARY.md file
Oct 22, 2021
dac77ed
Merge branch 'main' of github.com:celo-org/docs into victor/account-r…
Oct 28, 2021
380c0a6
add redirects
Oct 28, 2021
b5095d0
Apply suggestions from code review
Oct 28, 2021
3416fde
fix mixing of pronouns in Identity overview
Oct 28, 2021
640cc58
edits while reading through the docs changes
Oct 28, 2021
9867531
OPRF -> POPRF
Oct 28, 2021
e7ef827
Apply suggestions from code review
Oct 28, 2021
d6c4499
Merge github.com:celo-org/docs into victor/account-recovery-docs
Nov 23, 2021
993dc2f
Merge branch 'victor/account-recovery-docs' of github.com:celo-org/do…
Nov 23, 2021
37d23e4
fix bad merge in sidebar
Nov 23, 2021
3d86ab1
clarify the meaning of POPRF
Nov 23, 2021
47e726f
add section on how to create a new domain
Nov 23, 2021
6fdde82
fix broken link
Nov 23, 2021
501afa1
Apply suggestions from code review
Nov 23, 2021
84aca9e
add more information about the implementation of encrypted cloud backup
Nov 24, 2021
8ceeead
Merge branch 'victor/account-recovery-docs' of github.com:celo-org/do…
Nov 24, 2021
3827042
remove 'en.' from wikipedia links
Nov 24, 2021
2c49351
Merge remote-tracking branch 'origin/main' into victor/account-recove…
Apr 1, 2022
261fcf6
replace single with double quote
Apr 1, 2022
df79a56
minor edits
Apr 1, 2022
a8ef69a
a few more minor edits
Apr 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions docs/celo-codebase/protocol/identity/encrypted-cloud-backup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
title: Pin/Password Encrypted Cloud Backup (PEAR 🍐)
---

Secure and reliable account key backups are critical to the experience of non-custodial wallets, and Celo more generally.
Day-to-day, users store their account keys on their mobile device, but if they lose their phone, they need a way to recover access to their account.
Described in this document is a protocol for encrypted backups of a user's account keys in their cloud storage account.

## Summary

Using built-in support for iOS and Android, mobile apps can save data backups to Apple iCloud and Google Drive respectively.
When a user installs the wallet onto a new device, possibly after losing their old device, or reinstalls the app on the same device, it can check the user's Drive or iCloud account for account backup data.
If available, this data can be downloaded and used to initialize the application with the recovered account information.

Access to the user's cloud storage requires logging in to their Google or Apple account.
This provides a measure of security as only the owner of the cloud storage account can see the data, but is not enough to confidently store the wallet's account key.
In order to provide additional security, the account key backup should be encrypted with a secret, namely a PIN or password, that the user has memorized or stored securely.
This way, the users account key backup is only accessible to someone who can access their cloud storage account *and* knows their secret.

Because user-chosen secrets, especially PINs, are susceptible to guessing, this secret must be [hardened](https://wikipedia.org/wiki/Hardening_(computing)) before it can be used as an encryption key.
Using [ODIS](/celo-codebase/protocol/odis) for [key hardening](/celo-codebase/protocol/odis/use-cases/key-hardening), this scheme derives an encryption key for the account key backup that is resistant to guessing attacks.

With these core components, we can construct a cloud backup system that allows users who remember their password or PIN, and maintain access to a cloud storage account, to quickly and reliably recover their account while providing solid security guarantees.

Valora is currently working to implement encrypted cloud backup, using the user's access PIN for encryption.

### Similar protocols

- [iCloud Keychain](https://support.apple.com/guide/security/secure-icloud-keychain-recovery-secdeb202947/web) uses 6-digit PIN, hardened by an HSM app, and encrypt iCloud Keychain backups.
- [Signal SVR](https://support.apple.com/guide/security/secure-icloud-keychain-recovery-secdeb202947/web) uses a 4-digit PIN or alphanumeric password, hardened by an Intel SGX app, to encrypt contacts and metadata.
- [Coinbase Wallet](https://blog.coinbase.com/backup-your-private-keys-on-google-drive-and-icloud-with-coinbase-wallet-3c3f3fdc86dc) uses a password encrypted cloud backup to store user account keys. It is unclear if any hardening is used.
- [WhatsApp E2E Encrypted Backups](https://engineering.fb.com/2021/09/10/security/whatsapp-e2ee-backups/) uses [OPAQUE](https://datatracker.ietf.org/doc/draft-irtf-cfrg-opaque/) to harden a password encrypted backup
- [MixIn Network TIP](https://github.com/MixinNetwork/tip) uses 6-digit PINs, hardened by a set of signers, to derive account keys

## User experience

Here we describe the user experience of the protocol as designed.
Wallets may alter this flow to suite the needs of their users.

### Onboarding

During onboarding on a supported device, after the PIN or password is set and the account key is created, the user should be informed about cloud backup and given a chance opt-out of cloud backup for their account.
If they opt out, the rest of the setup should be skipped as they will not be using cloud backup.

On Android, when the user opts-in, they should be prompted to select a Google account that they would like to use to store the backup.
On iOS, the user need not be prompted as there is a single Apple account on the device and the permissions architecture allows access to application-specific iCloud data without prompting the user.

In the background, the chosen PIN or password and a locally generated salt value should be used to query ODIS.
The resulting hardened key should be used to encrypt the BIP-39 account key mnemonic.
The encrypted mnemonic and metadata, including the salt, should be stored in the user's cloud storage.

### Recovery

During recovery, the application should determine if a cloud backup is available.
On iOS, this can be done automatically.
On Android, the user may choose to restore from cloud backup, at which point they should be prompted to choose their Google account.

If a backup is available the user may select to restore from cloud backup, at which point they should be asked for their PIN or password.
Given the PIN or password, the application should combine it with the salt value and query ODIS to retrieve the hardened key for decrypting the account key backup.
If successful, the user will be sent to the home screen.
If unsuccessful, the user will be given the option to try again or enter their mnemonic phrase instead.

Users should, by requirement of security, be given a limited number of attempts to enter their PIN or password.
Attempts should be rate limited with a certain number of attempts available immediately (e.g. 3-5 attempts within the first 24 hours), and a limited number of additional attempts available after one or more waiting periods (e.g. up to 10-15 attempts over 3 days).
Once all attempts are exhausted, the backup will become unrecoverable and the user will only be able to recover their account if they have their mnemonic phrase written down.

## Implementation

Client support for the encrypted backup protocol described here is implemented in the [`@celo/encrypted-backup` package](https://github.com/celo-org/celo-monorepo/tree/master/packages/sdk/encrypted-backup).

Creating a backup file consists of a number of steps to derive the encryption key, and assemble the backup file.

1. Generate a random nonce and hash it with the password or PIN input to get the initial key.
2. Generate a random fuse key and hash it with the initial key to get an updated key.
Encrypt this fuse key to the public key of the circuit breaker service and discard the plaintext fuse key.
3. Send the key as a blinded message to the ODIS to be hashed under a [password hardening domain](/celo-codebase/protocol/odis/use-cases/key-hardening).
Use an authentication key derived from the backup nonce such that only a user with access to the backup can make queries to ODIS.
Hash the response from ODIS together with the key to generate the hardened key.
4. Encrypt the account mnemonic phrase with the hardened encryption key, and assemble it together with the nonce, ODIS domain information, encrypted fuse key, and environment metadata for ODIS and the circuit breaker.

If the implementing service does not wish to include a circuit breaker, which is described in more detail below, step two can be skipped.

The backup file created in this protocol can then be stored by the wallet that implements this protocol in some authenticated storage, such as iCloud or Google Drive.

In order to open the backup and recover the users account mnemonic the encrypted backup file is first retrieved from authenticated storage, then the decryption key is derived in the following steps similar to the steps above.

1. Hash the password or PIN input with the nonce in the backup to get the initial key.
2. Query the circuit breaker to unwrap the encrypted fuse key and hash it with the initial key to get an updated key.
3. Send the key as a blinded message to the ODIS to be hashed under the included [password hardening domain](/celo-codebase/protocol/odis/use-cases/key-hardening).
Use an authentication key derived from the backup nonce.
Hash the response from ODIS together with the key to generate the hardened key.
4. Decrypt the backup data with the hardened decryption key and return it as the account mnemonic.

### Circuit breaker

In order to handle the event of an ODIS service compromise, this is protocol includes a recommended circuit breaker service.
A circuit breaker service is essentially an online decryption service with a well-known public key that can be taken offline if needed to prevent access to the decryption key.
By using a fuse key which is decrypted to the circuit breaker service, and therefore can only be accessed if the service is online, as a step to derive the encryption key for the backup, the circuit breaker service operator is able to disable decryption of backup files in case of an emergency to protect user funds.
In particular, if the ODIS key hardening service is discovered to be compromised, the circuit breaker operator will take their service offline, preventing backups using the circuit breaker from being opened.
This ensures that an attacker who has compromised ODIS cannot leverage their attack to forcibly open backups created with this function.

### PIN Blocklist

When using a 4 or 6 digit PIN code to encrypt a backup, there are a number of PINs that are far more common than common than others.
Sequences (123456), patterns (124578) and important dates (110989) are chosen most frequently.
Within 30 guesses, an attacker has a 5-9% chance of guessing a users first-choice PIN code, as suggested by [research into PIN security](https://this-pin-can-be-easily-guessed.github.io/).
In order to address this, it is highly recommended to block the most easily guessed PINs.
One way to do this is to block PINs that are most popular.
A suggested implementation, which is [implemented by the Valora wallet](https://github.com/valora-inc/wallet/blob/3940661c40d08e4c5db952bd0abeaabb0030fc7a/packages/mobile/src/pincode/authentication.ts#L56-L108), is to create a blocklist from the top 25k most frequently seen PINs in the HIBP Passwords dataset.
8 changes: 4 additions & 4 deletions docs/celo-codebase/protocol/identity/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ Celo’s unique purpose is to make financial tools accessible to anyone with a m

### Adding their phone number to the mapping

To allow Bob to find an address mapped to her phone number, Alice can request attestations to their phone number \(technically the hash of their phone number\) from the `Attestations` contract by transferring the attestation request fee to it. The fee per attestation request is set on the contract with [Governance](celo-codebase/protocol/governance.md). After a brief waiting time of currently `4` blocks, the `Attestations` contract will use the `Random` contract to do a random selection over the current validator set in the `Validators` contract who will become responsible for these attestation requests.
To allow Bob to find an address mapped to her phone number, Alice can use the decentralized attestations protocol to link an account address to her phone number. Alice starts by making a request to the `Attestations` contract; transferring a fee along with her request. After a brief waiting time of `4` blocks (20 seconds), the `Attestations` contract will use the `Random` contract to produce a random selection of validators, from the current elected set in the `Validators` contract, to issue the attestation challenges.

As part of the expectation to validators, they run the attestation service whose endpoint they register in their [Metadata](/celo-codebase/protocol/identity/metadata.md). Alice can identify the validators responsible for her attestation from the smart contract, determine the validators' attestation service URLs from their [Metadata](/celo-codebase/protocol/identity/metadata.md) and request attestations from them. In turn, the attestation service produces a signed secret message that acts as an attestation by that validator that Alice owns the phone number. The validator sends that message via SMS. Read more under [attestation service](#attestation-service).
As part of the expectation of validators, they run the attestation service whose endpoint they register in their [Metadata](/celo-codebase/protocol/identity/metadata.md). After attestation issuers have been selected for their requests, Alice determine the validators' attestation service URLs from her [Metadata](/celo-codebase/protocol/identity/metadata.md) and requests an attestation message to her phone number by sending a direct HTTPS request. In turn, the attestation service produces a signed secret message attesting to the ownership of the given phone number by the requesting account. The validator sends the message to Alice's phone number via SMS. Read more under [attestation service](#attestation-service).

When Alice receives the text message, she can take that signed message to the `Attestations` contract, which can verify that the attestation came from the validator indeed. Upon a successful attestation, the validator can redeem for the attestation request fee to pay them for the cost of sending the SMS. In the end, we have recorded an attestation by the validator to a mapping of Alice’s phone number to her account address.

Expand All @@ -28,13 +28,13 @@ Once Alice has completed attestations for their phone number/address, Bob, who h

The `Attestations` contract records all attestations of a phone number to any number of addresses. That for example could happen when a user loses their private key and wants to map a new wallet address. However, it could also happen through the collusion of a validator with Alice. Therefore, it is important that clients of the identity protocol highlight possible conflicting attestations.

Some risk exists for attestations to be added without the permission of the "legitimate" owner of the phone number. One such risk is that the phone service provider or [SIM swap](https://en.wikipedia.org/wiki/SIM_swap_scam) attacker could take control of the phone number and complete a number of attestations. Another risk is that a sufficient number of Attestation Service providers may collude to complete fake attestations. Notably, completing malicious attestations does not lead to a loss of funds, as the private key is still the necessary and sufficient condition for transactions of an account. However, without proper care, future senders may be tricked into sending funds to the newly associated address. In general the number and age of attestations for an address should be taken into account to identify the valid owner of a phone number.
Some risk exists for attestations to be added without the permission of the "legitimate" owner of the phone number. One such risk is that the phone service provider or [SIM swap](https://wikipedia.org/wiki/SIM_swap_scam) attacker could take control of the phone number and complete a number of attestations. Another risk is that a sufficient number of Attestation Service providers may collude to complete fake attestations. Notably, completing malicious attestations does not lead to a loss of funds, as the private key is still the necessary and sufficient condition for transactions of an account. However, without proper care, future senders may be tricked into sending funds to the newly associated address. In general the number and age of attestations for an address should be taken into account to identify the valid owner of a phone number.

There are additional measures we can take to further secure the integrity of the mapping’s usage. In the future we plan to provide reference implementations in the wallet for some of these. For example, we plan to detect remapping of wallet addresses. Many users are already accustomed to sending small amounts first and verifying the receipt of those funds before attempting to transfer larger amounts.

### Preventing harvesting of phone numbers

To protect user privacy by preventing mass harvesting of phone numbers, the Celo platform includes a service that obfuscates the information saved on the blockchain. The service is enabled by default for all Celo Wallet users. Details of its functionality and architecture are explained in [Phone Number Privacy](/celo-codebase/protocol/identity/phone-number-privacy.md)
To protect user privacy by preventing mass harvesting of phone numbers, the Celo platform includes a service that obfuscates the information saved on the blockchain. The service is enabled by default for all Celo Wallet users. Details of its functionality and architecture are explained in [Phone Number Privacy](/celo-codebase/protocol/odis/use-cases/phone-number-privacy.md)

### Attestation service

Expand Down
2 changes: 1 addition & 1 deletion docs/celo-codebase/protocol/identity/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ContractKit currently supports the following types of claim:

- **Keybase User Claim** - Accounts can make claims on [Keybase](https://keybase.io) usernames. This claim is verifiable by signing a message with the account and hosting it on the publicly accessible path of the Keybase file system.

- **Domain Claim** - Accounts can make claims on domain names. This claim is verifiable by signing a message with the account and embedding it in a [TXT record](https://en.wikipedia.org/wiki/TXT_record).
- **Domain Claim** - Accounts can make claims on domain names. This claim is verifiable by signing a message with the account and embedding it in a [TXT record](https://wikipedia.org/wiki/TXT_record).

In the future ContractKit may support other types of claim, including:

Expand Down
Loading