Jun 22, 2011

Encrypted Tweets

As a cryptography course project, me and @laisandrade developed a twitter extension which allows us to tweet in a way that only a group of followers can decrypt and understand my tweet. The goal is to secure broadcasting tweets to a group of followers and avoid anyone else to understand it's content. This definition of security is safe against a eavesdropping attack, which is considered secure enough for the common sense for cryptography, what is not true. Another concerns emerges when we consider other attacks or ways of extracting informations from the cyphertext, as an example the Known-Plaintext Attack.
Configuration of the Encrypted Tweets problem - Alice securely broadcasting messages to a specific group
In this project we should also consider other security issues such as forgery attacks and secure information storage. The only real world problem outside the project's scope was the private key distribution. We assume that the user who wants to share it's keys to his followers could use other mechanisms such as a Diffie-Hellman key exchange or using a trusted key broker. The full project's specification can be found here.

For doing the task we used the Grease Monkey Firefox's plugin. This plugin allow us to run custom javascript scripts in specifics web pages, so we can add functionalities to known web pages. In fact, we used a script stub for doing it. This script adds a encrypt tweet functionality as well as a key manager at password settings page. It also gives a function to store (unsafely) the user information. Was also our job to make it secure. We assumed that the script couldn't be cracked, the focus where we were concerned was about the information safety outside the script execution memory.

Encrypt button and Group selection close to Tweet button

============================== Encryption Specification ==============================

Encripted Message:
| "aes:" | Ctr | Extended-AES(Content, Ctr, GroupKey) |
* The Ctr is the base counter for the CTR block chaining cypher. Every message picks a random Ctr.
* The group key is the key to the group whom members are the only who should understand the message.
* The Extended-AES function will be detailed after.

* the "aes:" indicator is not a security threat due to Kerckhoffs's Principle.

| sha1(Message) | Message |
* The sha1 cryptographic hash is used to check the integrity of the stored keys and avoid modifications on the massage bypass as a real message.
* The sha1 produces a 160 bits length message, which is convertes into a base64 string to send it over twitter.

* This Message Authentication Code (MAC) is necessary for Chosen Ciphertext Security (CCA Security).

Message: the original message

For our Extended-AES implementation, we used a Cypher Block Chaining to extend the AES block cypher, that we use as a block cypher. To do this we used a Counter (CTR) chaining to extend the cypher. Note that the CTR mode uses a base counter (Ctr) as an Initialization Vector (IV) which also must be transmitted to enable to be decrypted. This IV is chosen at random by our pseudorandom generator. If the IV is not truly random, an attacker may predict the IV sequence and get more information from the message. A real problem faced by pseudorandom generators are when the seed selection are not truly random. To handle this, the script stub creates a seed using the mouse positions at the first seconds of running (an entropy test is also used to check the randomness of the seed).

When someone receives a "aes:" tagged message, the script checks the author of the message and get the key provided by him. To decrypt, we also use the Extended-AES since it is symmetric (due to XOR reversibility property). At last the SHA-1 hash is confronted with the message to check if the key is correct or the message suffered a forgery attempt.

To store the groups keys we used the grease monkey's key value storage (GM_setValue and GM_getValue functions). We store and recover the values from the key "twit-key-" + login, which is stored as plaintext in the hard drive. To avoid the stealth of this information from other users, virus or worm we added an encryption layer over it. The stored data representation developed was this one:

Keys management screen

==============================   Safe Storaging Specification   ==============================

Stored Data:
AES(Data, MasterKey)

User secret key to access all the other keys. This key requires user input every time it logs in.

|   sha1(GroupKeys)   |   Groups Keys   |
* This cryptographic hash is used to check the integrity of the stored keys.
* A malicious agent may override the values on the keys and may set the keys he can decrypt.

Groups Keys:
|   Item   |   "$$"   |   Item   |   "$$"   |   ...   |   "$$"   |   Item   |

|   User   |   "$"   |   Group   |   "$"   |   Key   |

User: base64 string
Group: base64 string
Key: base64 string


It's important to notice that we implemented the SHA-1 hashing algorithm to ensure the data wasn't modified while stored or transmitted. We trust it wasn't modified due to the difficulty to crack the AES cypher to forge a new MAC. And if the attacker try to change bits from the stored data, we trust that SHA-1 hash collision difficulty will be enough to ensure us that someone will be able to produce valid message, hash pairs without looking at the plaintext. If the pair is corrupted, then the user is alerted that someone modified his keys. By doing this, we may disable an attacker to modify bits from our keys and have better chances to crack the scheme. The SHA-1 also has some theoretical weakness, however, in practice it still is a very strong cryptographic hash function.


  1. To be really secured this scheme needs to address two issues (at least)
    - Availability. Suppose evil twitter staff chose to remove some of the messages. ¿How do you avoid this? (At least notice it). Perhaps if you implemented like a counter for every twitter, you'll detect seldom blocks. Yet to defend against full blocking, i guess you'll need two twitter accounts following each other or something like that.
    - Re-keying. What if some of the keys where compromised? ...

    Yet I like the idea. Also i would lose the base64 encoding to get more chars, because twitter accepts UTF-8 posts. Maybe an encoding losing \0 and \n, I don't know... it could work.

    1. 1 - The counter-in-the-end scheme can't ensure deletion because you can fake deleted tweets. We may have other kind of exploits to comprimise the service holder, because neither it or you can't prove if the tweet was really deleted. To make it work, the service would need to sign the message counter for you.

      2 - The users would have to change the key. This problem by itself is complex enough to be an exclusive cryptography area.

      3 - That's true, I could improve the cypto scheme at this point.

      Sorry for the delay.

  2. Im new to cryptography. I used given script stub. script added a key manager at password settings page but not added a encrypt tweet functionality(there were no button added). What can be the possible reason?

    1. Maybe the twitter page HTML was changed. You have to check the id's of where the button is being added.