GSoC17 : Client Side File Crypto : week 8

Submitted by tameeshb on Wed, 07/26/2017 - 13:23

This blog post summarises the eighth week of writing open-source code for Drupal with Google Summer of Code. 

This week I nearly completed the final encryption JS script and moved to the decryption part of the module that is the last major functional component.

Commit map

File Encryption Updates

I added a custom field on the form to take file inputs that would accept all file types for the user file input that is to be encrypted by this module.
There were several limitations on using the default fileinput field as it would require additional configuration from the system administrator, the file types that can be uploaded are also limited and there are JS methods that are bound to the change event of those fields not overridden by event.preventDefault().

Encrypt file input

I also added new AJAX methods that would send the file asynchronously to the backend leveraging the FormData() API and BLOB objects in JavaScript to mock a form field which is better and a more elegant method than what I was using before :

var body = '--' + boundary + '\r\n'
// Parameter name is "file" and local filename is "temp.txt"
+ 'Content-Disposition: form-data; name="file";'
+ 'filename="' + file_name + '"\r\n'
// Add the file's mime-type
+ 'Content-type: ' + file.type + '\r\n\r\n'
// Add your data:
+ encrypted + '\r\n'
+ '--'+ boundary + '--';


var formData = new FormData();
formData.append('file', new File([new Blob([encrypted])], file_name));
formData.append('another-form-field', 'some value');

File Decryption Sandbox

I started off testing my decryption scripts inside a decryption sandbox. For testing purposes I added a download method on the event when the file is selected on the new node page. I also added another file field on the same page to test out the decryption on the same page.

Decrypt Sandbox

So now, once you select file on the “Encrypted file” field, it would download the ciphertext file with the name encrypted_filename.extension and that file can then be dragged to the “Decrypt file” field and that would decrypt that file and download the cleartext file for that file. This worked as expected for plain text files but didn’t quite work initially for binary files like images.

Result with binaries:

Binary error

Trouble with binaries!

As mentioned in the previous image, the binary files (eg: images) were not working with the JS code I wrote. It turned out that I was using the wrong decoding while decrypting the file as the encrypting was just fine. The CryptoJS library automatically handles base64 encoding though.
Here is what the original image looked like when opened in a text editor:

Binary original

But the file output I was getting was in a different character-set:

base64 of binary

Base64 not converted using .toString(CryptoJS.enc.Latin1)

Base64 not converted using .toString(CryptoJS.enc.Latin1)

After a while of looking around on the internet I figured I had to download the binary files using the “data:application/octet-stream” MIME type on an anchor with the “download” tag and trigger clicking on it using JS.

Also, I could add an image preview to the page seeing how this website works during the “investigation”.

After a bit more modification, I could make this work with all MIME types and tested it with plain-text, images and pdf files and then moved this code to the js_decrypt branch to attach it to all the pages where these encrypted files would be displayed.

Youtube screen-recording video demonstrating the decryption sandbox.

Also, the second phase evaluations would be this week and this week would be the end of the second month of the coding period in Google Summer of Code. As most of the time has elapsed, so is development for most major parts of the module. The only parts left to be done are for customisability of the implemented features so far and writing tests and documentation. I’ve started looking into writing tests which I’m going to continue this week along with altering the file preview methods on the view article pages. After discussion with my mentors in this week's meeting, it was decided that we will be giving a higher priority to writing functional tests than unit tests, so this week I will also be writing functional tests.

Thanks for reading!

Recent content