Decrypting and encrypting CSEv1r1 encrypted objects requires the CSEv1 keychain.
Decrypting an object
The property cseKey stores the uuid of the key which was used to encrypt the object.
If this no key with this uuid in the keychain, the object can not be decrypted.
Note: The key is the same for every value in the same object, but the nonce is of course different for each value.
The encrypted values are stored as hexadecimal encoded strings and need to be decoded before they can be decrypted.
Important: Prior to Passwords 2020.2.0 the encrypted value string was encoded with base64.
Users who set up CSE before the official release may have objects with base64 encoded values which should be taken into account.
Before the decoded value of any property can be decrypted, it needs to be split into the nonce and the cipher text.
The nonce are the first crypto_secretbox_NONCEBYTES bytes of the keychain string.
The cipher text comes after the first crypto_secretbox_NONCEBYTES bytes.
With the cipher text, the nonce and the key, crypto_secretbox_open_easy can be used to decrypt the value.
The cipher text is used for c, the nonce is n and key is k.
The result is the plain text value for the property of the object.
Encrypting an object
To encrypt an object, the current encryption key needs to be fetched from the keychain.
Note: It is not necessary or intended to create a new key for every object that is encrypted.
This will only increase the size of the keychain and does not improve security at all since all keys are encrypted with the same master password.
Before a value of any property can be encrypted, a nonce with the length of crypto_secretbox_NONCEBYTES with random data needs to be created.
Libsodium provides the function randombytes_buf to generate secure random data.
Important: Always generate a new nonce when encrypting a value and never re-use a previously used nonce.
With the value, the nonce and the key, crypto_secretbox_easy can be used to encrypt the value.
The value is used for m, the nonce is n and encryption key is k.
Then, the nonce is prepended to the encrypted value.
(Encrypted Value = nonce + value)
Finally, the resulting string is encoded as hexadecimal string.
After encrypting the object, the property cseType has to be set to "CSEv1r1" and the property cseKey to the uuid of the used encryption key.