-
Notifications
You must be signed in to change notification settings - Fork 0
Message History
Message history is encrypted and saved locally on disk (at rest encryption).
Message history is saved automatically by the client when the unencrypted messages are displayed in the GUI chat window. The message history is saved as history (.his) files, with the name of the file being the recipient's username. The history (.his) files themselves are saved under the user's directory.
To view message history, the user selects the Message History
option from the main menu, which prompts the user for a message history with a specific recipient to view and re-authenticates the user with their password. This is necessary to gain access to the user's private RSA key which is subsequently used to decrypt the records in the history (.his) file.
Message history uses a hybrid cryptosystem of AESGCM and RSA.
RSA was chosen because it is a strong and assymetric. Asymmetry allows the client to encrypt save message history with the public key. Thus, the message history can only be accessed with the private key, forcing the viewer to re-authenticate themselves with their password to prove they are the rightful owner before being given access.
Originally, message history was encrypted with only RSA; however, the maximum length of data that could be encrypted with RSA is only 190 bytes. To support encrypting longer messages, a symmetric key is used (AESGCM).
A private and public RSA key pair are created with a public exponent of 65537 and a key size of 2048. The keys are then serialized into PEMs and decoded into a UTF-8 string. The private key PEM requires the user's password to be accessed.
A user folder is created for the user when they first login to their account on a device. Within this folder, a config.json
file is created. Generated RSA keys are written into the user's config.json
file where they are used as needed to support message history encryption and decryption.
The public RSA key is used to encrypt the AESGCM key and nonce (message key). The encryption is performed with OAEP padding using a Mask Generation Function (using SHA256 hashing) and SHA256 hashing algorithm.
The password-protected private RSA key is used to decrypt the message key. The decryption is performed with the same padding parameters as above.
AESGCM was chosen because it is an authenticated encryption scheme that provides message confidentiality and integrity while also being symmetric.
The generated AESGCM key is 128 bits long and uses a random nonce that is 12 bytes long.
Messages are encrypted with the AESGCM key and nonce generating the message ciphertext. The key and nonce (referred to as the message key), is then encrypted with the user's public RSA key. The message ciphertext is then appended to the encrypted message key, which is then written as a record to the history (.his) file. Records are delimited by a single newline character (\n
).
To decrypt a record from the history (.his) file, the record is divided into the message ciphertext and the encrypted message key.
First, the encrypted message key is decrypted with the user's private RSA key (password-protected). Then, the message key (key and nonce) are used to re-generate the AESGCM and decrypt the message ciphertext to plaintext.