Skip to content

Message History

Gordon Chiang edited this page Dec 4, 2021 · 4 revisions

Message history is encrypted and saved locally on disk (at rest encryption).

Saving Message History

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.

Reading Message History

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.

Cryptosystem

Message history uses a hybrid cryptosystem of AESGCM and RSA.

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).

Key Generation

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.

Key Saving

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.

AESGCM 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

AESGCM was chosen because it is an authenticated encryption scheme that provides message confidentiality and integrity while also being symmetric.

Key Generation

The generated AESGCM key is 128 bits long and uses a random nonce that is 12 bytes long.

Message Encryption

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).

Message Decryption

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.