On Tuesday evening I delivered a presentation to a fairly diverse group comprised of local IT business owners and staff – the largest of it’s kind in my city. The subject of it was incident response: hiring the right staff and educating existing staff, designing networks that reduce the impact of breaches, log correlation and malware analysis, etc. One point that I made, which visibly provoked deep thought throughout much of the audience, was that shifting infrastructure into the cloud moves our data further out of the reach of security controls and into the hands of potentially untrustworthy and incompetent 3rd parties. You may say: “well, duh”. Trust me, it too came as a surprise to me that this would cause distress for people, as in my mind it’s absolute common sense – but obviously not. The concern of outsourcing security was, however, one of the reasons that I chose to introduce a policy within my workplace that prohibits the transmission of confidential data (e.g. credentials) via email or SMS, as data retention and the security of cloud and telco services is at times somewhat questionable. So, you want to eliminate the storage of confidential information in any such outsourced services. Faced with having to devise a solution that is usable by even the most technically inept, I decided to build upon a concept already used by some online services: self-destructing, encrypted messages.

why reinvent existing services?

My main issue with them stems from my belief that any application that handles any form of a secret needs to be open source in order to be trusted as you must be able to ascertain:

  • The code is free from vulnerabilities.
  • The cryptography standards are suitable for the purpose.
  • The application is not siphoning out secrets.
Additionally, I wanted to produce a flexible and pleasant experience – catering for varying levels of paranoia and user ability:
  • The design is very basic and clean.
  • The application is very usable in desktop, tablet and mobile browsers.
  • Users can create notes that require only a link, require an additional 6-character key and/or perform all cryptography in the browser to ensure the message, link and key are never sent to the server in plaintext.

 

how does the service work?

Let’s create a case scenario with Alice and Bob. Alice wants to send a secret to Bob, so she visits DeadDrop:

Alice enters a message into the form:

If she forgets to enter some text into one of the fields, doesn’t complete the reCAPTCHA challenge or enters an invalid email address she get’s a pop-up (toast) on her screen informing her of this:

Once her entry is complete, she clicks on submit and see’s a nice animation as the request is processed:

If she checked “Require TFA” she’ll receive both a link and 6-character key to send to Bob:

Otherwise she’ll only need to send him a link:


a single click of the link will highlight the entire text

In any case, the link contains two query strings:

  • id: used to fetch the correct record from the database.
  • key: used to decrypt the message.

The manually-entered TFA key is an extension of the key used to encrypt the message.

In this case Bob is a bit paranoid that his employer might be snooping in on his emails, so as the link is being sent to him via email, Alice sends him the TFA key via an out-of-band method: SMS.

When Bob visits the link he is requested to enter the TFA key:

Upon successfully entering it, he’s shown the secret message:

However, if he were to try and visit that link again, or if he were to enter the incorrect TFA key – he’d be shown an error message as the message either would not exist or would fail to decrypt:

Alice is also sent an email confirming to her that Bob has successfully opened the message and that it has been deleted from the database:

Should Bob be paranoid to the extent that he is concerned his employer may have a puppet at the host of the application, then he could request for Alice to uncheck “Trust Host” so that key generation, encryption and subsequent decryption is all performed only in the browser (where at least he can still view and critique the Javascript).

application construction

DeadDrop is an ASP.NET application, using SignalR for real-time server-client communication. The database platform is PostgreSQL, however only uses a single table – as that’s all that is required. Providing the host is trusted, all cryptographic operations are performed by a separate WCF service (CryptoService) that has several roles:

  • Key Generation: Leveraging the MS RNGCryptoServiceProvider class, cryptographically secure random strings can be generated of variable length.
  • Encryption: Inferno is used to perform AES256 CTR + HMAC-SHA384 EtM encryption. Messages are encrypted using a random key, and all other data (note descriptions and email addresses) is encrypted using a key and payload that is defined in the web.config of the service. EtM ensures that encryption is authenticated.
  • Hashing: CryptSharp is used to generate salts, and hash keys using scrypt (for verification purposes when requesting a note).

In the case that the user does not trust the host and opt’s for in-browser cryptography, the standards are much the same:

  • Key Generation:RandomSource.getRandomValues() ensures that sufficient entropy is used to generate random strings – typically where browsers fall short.
  • Encryption: A combination of Forge and the Stanford Javascript Crypto Library encrypts messages using AES256 CTR + HMAC-SHA256 EtM prior to transmission to the server. On the server they’re protected at rest by additional encryption.
  • Hashing: Whilst not specifically hashed in the browser, keys are stretched prior to transmission to the server by 86,000 rounds of PBKDF2 also using Forge. On the server they’re hashed the same as other keys using scrypt.

Lately I’ve been inspired by Google’s Material Design, which led me to stumble upon Materialize – an awesome framework for developing interfaces that adhere to it’s principles. Using it is incredibly easy (I cannot stress this enough), it’s responsive and it offers some pretty advanced features that would be quite difficult to implement from scratch. It obviously ties in quite nicely with reCaptcha v2 too!

summary

Developing this application hasn’t really stretched my development ability at all, however working alongside our UX team has given me a newfound appreciation for putting serious thought into application usability. The design aspect of DeadDrop isn’t quite finished so it hasn’t passed the eyes of any of our clients yet (the true test), however our helpdesk staff have begun using it internally and I’ve received nothing but positive feedback.

You can view the source code on GitHub.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s