GSoC Week 7: encrypt_content_client - decryption of nodes

New table for encrypted fields

I encountered a limitation when encrypting fields, for example when encrypting the title field, the JSON object returned from the symmetric function may be longer than title’s maximum length. After talking to Colan and Talha we agreed that I should follow a similar approach used in the encrypt module. So I included another table which now gets created on the module’s installation:

Encrypted Fields Table

 

I also had to change my code a bit, but I got the most important functions done already so adapting to these new requirements was a breeze.

More robust way of getting form’s node and type

After reading this article I made sure I switched from using a simple regex to a more robust way of getting the current form’s entity type. Now my module uses hook_form_node_form_alter that attaches to the node’s create and edit forms. This hook also gets the node’s ID, if it’s set to null then the form must be creating a new node, if it exists - it’s an edit form. This is a robust way of determining the information that is crucial for my module.

Decryption process

Here a list of steps needed in order to implement decryption of nodes in my module.  This will change a bit as I am working on a more robust design. Below is an example of decryption when editing a node:

  1. Call the REST resource with current entity type and ID, resource returns data-key key encrypted for every user:

  1. Format output to an JSON object and then select the one for currently logged in user.

  2. Get user’s private key stored in localStorage and build an private key object using hex representation.

  3. Unserialize ECC private key - transform hex representation to an object:

  4. Use sjcl.decrypt function providing the key object and encrypted JSON as a string.

  5. Having data-key in plaintext call the sjcl.decrypt function again in order to use symmetric algorithm AES and go through encrypted fields in order to get plaintext.

  6. Replace fields with encrypted content as soon as the page loads so the user can edit the node.

Below is a basic code implementation of above steps, along with some debugging lines.

Decrypt Code

Decrypting content

With the above change in place I was able to easily finish implementing decryption of nodes. When an user wants to edit encrypted node’s details the data must be decrypted when the page is opened and the fields populated with plain text before user can click the save button and encrypt it again.

Decryption of nodes

I will not be going into manually decrypting more fields for now as in the next week I will be working on a more robust way of selecting which fields to encrypt, as well as storing encrypted strings in a separate table instead of storing them in node's fields.

Interesting issues

  • SJCL library errors:

    • invalid aes key size

    • ccm: tag doesn’t match

I was getting two of the above errors when trying to use the SJCL library. After investigation and trying to isolate the issue on my local server without Drupal I managed to fix it. Instead of having included separate files that I thought were needed I followed the instructions and used node’s CLI command to generate a single file with the option --with-ecc, which gave the minified file that I then included in my library.

The second error occured when trying to decrypt ciphertext, the issue was caused by the way I was unserializing public and private keys (turning a hex string into SJCL objects).

Plans for week 8

  • Create a config page where admins can choose which entities to encrypt and what fields should be encrypted.

  • Store above configs as JSON in database table.

  • Now that the basic encryption process is in place, I can extend it to make it more robust.