In 2015, I had an idea for a potentially innovative cloud service called CreationGuard. The concept behind CreationGuard was that users would be able to upload text, passwords, documents, code, or images securely, in such a manner that only the sender and receiver would be able to view the data, not the website hosting it. Many services have implemented this concept, but require both the sender and receiver to download an app. CreationGuard would provide this feature using the user's browser only, without requiring any login for either the sender or recipient.


Cryptographic Design


In-browser cryptography can be very difficult to implement. In particular, because JavaScript has a very limited ability to provide necessary entropy. To solve this problem, I used a variety of sources.

First, each web page included several bytes of entropy that was generated by the server into a hidden element in the HTML. The purpose of this was to provide a baseline from which JavaScript could provide additional entropy. Although the server could use this entropy to gain insight into the content of the encrypted data, this trade-off is better than the alternative of having data encrypted with insufficient entropy in certain environments.

To build upon the server entropy, I added code to extract entropy from browser APIs. These APIs are only supported in modern browsers, but when available, provide a very solid source of JavaScript entropy. As a final fallback, the system uses Stanford's JavaScript cryptography library to gather entropy from mouse motions. This is a good source of random entropy, however, it can be very awkward to require the user to move their mouse before proceeding with a file upload. It is better to use sources of entropy from the browser or the server when they are available.


Each secret uploaded to the system has an access key and an encryption key. The access key is simply a random token generated by the server, which someone will need to know in order to retrieve an encrypted copy of the secret. The encryption key is a secret that is used to perform the actual decryption, once the secret is retrieved. This key is generated by the client using the entropy mentioned above.

Whenever a user uploads a secret, the client-side code creates a URL that can be used to access to secret. That URL includes the access key, as a parameter passed to the server, and the encryption key, as a parameter that is not passed to the server. The encryption key is stored to the right of a hashtag in the URL, which will make that data available to the client side, but not to the server side (unless JavaScript on the client side actively sends that data). When the secret is uploaded, it is encrypted using AES and then encoded into an easily machine0readable JSON string. Once a client retrieves the data, that JSON string is read. The cryptotext is extracted from the JSON, and then decrypted using the encryption key that is stored to the right of the hashtag in the URL.


With any cloud service, it's a bad idea to store data on the same server as the actual website. Web servers typically have a low amount of disk space, and it is very difficult to distribute the site across multiple web servers without using a separate server for data storage. To solve this problem, I decided to store data in two places.

Basic metadata is stored within a MySQL database. For now, that database is on the same server as the web service, although it could easily be moved to a separate server if the load volume became too great for a single server to handle. The actual secrets are stored in Amazon S3. Since they are encrypted by the client before even being sent to the server, amazon could never be able to read the data themselves without having access to a vurnerability in the AES algorithm.

Design Drafting Process

I started by doing some basic market research. From a quick google search, I found a few other sites that provide similar services. However, their user experience was not quite up to the standards for ease of use that I would require for this project. One required the user to enter a password on both ends. This is unneeded effort on the part of the user, because the service could instead generate a password randomly and embed it into the sharing link. Many cloud services do this, but again, require registration to be used.

My user interface concept for this project revolved around presenting the user with the submission form as quickly as possible. Optimally, they should be able to see all the controls they need to upload their secret without scrolling down the page any. To accomplish this, I structured the homepage with a logo and nav bar at the very top, followed by a basic banner describing the product to get them primed for the main content of the website. Next, I added the secret upload form, followed by a submit button, and then further explanation text to help them understand the technology behind the site.


The concept behind the secret uploaded (the portion of the site with a white background, seen above) is that the user would first select the type of secret they would like to upload (message, password, file, image), then type in or upload the secret. Next, they would enable the features they desired using "switch" controls below, and provide additional details as needed, such as the amount of time the service should wait before deleting the secret.

After designing the initial form, I then proceeded to design the sub-forms that would allow them to enter additional parameters for their upload. Below is a screenshot of the form design in Adobe Illustrator. The headings indicate which of the checkboxes the form is associated with. Clicking one of the checkboxes on, or clicking on its "configure" button would open up that form below the main form.

Screenshot Screenshot