Confirmed users
358
edits
Line 67: | Line 67: | ||
== Sync Key Encryption == | == Sync Key Encryption == | ||
Before uploading to the service, the client encrypts the sync key using its existing standard encryption routines. The encryption key is derived from the username and password using PBKDF2. The details that follow are just to explain the process - in the client code this should | Before uploading to the service, the client encrypts the sync key using its existing standard encryption routines. The encryption key is derived from the username and password using PBKDF2. The details that follow are just to explain the process - in the client code this should be a thin layer on top of existing methods such as Utils.deriveKeyFromPassphrase and CryptoWrapper.encrypt. | ||
To encrypt the sync key for storage in the recovery service, the client uses PBKDF2 to derive an appropriate encryption key from the user's account username and password: | To encrypt the sync key for storage in the recovery service, the client uses PBKDF2 to derive an appropriate encryption key from the user's account username and password: | ||
Line 74: | Line 74: | ||
enc_key = PBKDF2(username + password, salt, 4096, 32) | enc_key = PBKDF2(username + password, salt, 4096, 32) | ||
This is then used to encrypt the sync key via AES-256, with a random IV and | This is then used to encrypt the sync key via AES-256, with a random IV and HMAC-SHA256: | ||
IV = get_random_bytes(32) | IV = get_random_bytes(32) | ||
ciphertext = AES-256-ENCRYPT(enc_key, IV, sync_key) | ciphertext = AES-256-ENCRYPT(enc_key, IV, sync_key) | ||
hmac = | hmac = HMAC-SHA256(enc_key, ciphertext) | ||
The | The information necessary to decrypt the sync key is serialized into a JSON structure, which is sent to the key recovery service for storage: | ||
recov = { | recov = { | ||
Line 99: | Line 99: | ||
enc_key = PBKDF2(username + password, recov["salt"], 4096, 32) | enc_key = PBKDF2(username + password, recov["salt"], 4096, 32) | ||
if | if HMAC-SHA256(enc_key, recov["ciphertext"]) != recov["hmac"]: | ||
ABORT! | ABORT! | ||
sync_key = AES-256-DECRYPT(enc_key, recov["IV"], recov["ciphertext"]) | sync_key = AES-256-DECRYPT(enc_key, recov["IV"], recov["ciphertext"]) |