You are on page 1of 4

Peer-to-peer social networking in ShyChat

Hatem A. Mahmoud
Khawarezm
Khawarezm@icloud.com

I. INTRODUCTION & BACKGROUND


The basic promise that the cloud provides is to reduce the
entrance barrier for tech startups through a pay-as-you-go
policy. A startup can launch an online store or a web service
with minimal budget for IT infrastructure, then pay for traffic,
processing, and storage as its client base grows. This assumes,
however, that revenues grow linearly as a function in
infrastructure utilization, or at least that the two signals,
utilization and revenues, are correlated enough. This is not
always the case. For example, social media typically have to
create a sizable and stable client base before experimenting
with paid features. When developing our social app, ShyChat,
we take a low-risk approach by distributing the storage and
processing load over client devices. We use the cloud only as
a router; by utilizing the free Google Cloud Messaging
(GCM) service. On top of that routing service, we build our
handshaking protocol for client devices to recognize and
exchange encryption keys with one another.
Google Cloud Messaging (GCM) is a pub-sub service that Fig. 1. Anonymous chatting and anonymous tweets in ShyChat
provides app developers with a set of APIs through which apps can
define communication channels, also known as “topics”, and
exchange messages amongst each others by subscribing, posting, and receiving messages to and from these channels in JSON
format. A communication channel accepts up to a maximum number of subscribers. Published messages are “pushed”
downstream to subscribers. If a subscriber is not online when a message is pushed, the message is buffered in the cloud up to a
maximum period of time beyond which the message is lost if the subscriber have not shown up so far. There is also a maximum
number of buffered messages that a communication channel may accept. These upper bounds allow the free version of the GCM
service to scale out without charging end users.
The rest of the paper is organized as follows. First, we explain how we build our communication setup on top of the GCM
pub-sub service. Next, we elaborate on our handshaking protocol for secure peer-to-peer communication. Then we present the
various use cases for which our communication setup and our handshaking protocol are useful for our app, ShyChat. Finally, we
present our demo.

II. COMMUNICATION SETUP


In this section we explain the communication setup that we build on top of Google Cloud Messaging. Most of the technical
details that we explain in this section are not visible to end users of ShyChat (or any other application that we may build using
this communication setup) except for advanced features such as SMS verification and GCM peer checking. The main qualities
that we consider when developing our framework are robustness and privacy.
In ShyChat, each app instance installed on a smartphone defines on behalf of the user two communication channels on GCM:
(1) a broadcast channel through which this app instance posts messages to whom it may concern, and (2) a receptive channel
through which this app instance accepts messages sent specifically to this particular phone. For example, if ShyChat is installed
on a smartphone whose number is 1234-56789, the broadcast channel would be labeled BC_123456789, and the receptive
channel would be labeled RCV_123456789. During the installation of ShyChat on a smartphone, ShyChat retrieves the phone
number of this phone and uses it to “register” with GCM. Registration is done through Google Play APIs; if these are not
available the user is prompted to install them. If registration is successful, ShyChat is given a GCM “token” unique to this app
instance. Through this token, ShyChat subscribes to the channel RCV_123456789 to start receiving messages sent specifically
to this phone. The two operations, registration and subscription, together form a transaction that has to be executed atomically.
That is, ShyChat does not record the GCM registration token locally on the phone’s file system until subscription to the channel
RCV_123456789 is successful, since otherwise the app may crash and retry subscription with a stale token. GCM tokens are
service-side identifiers, and are actually subject to unscheduled updates from the side of the service.
ShyChat also generates during installation a private-key/public-key pair using RSA (although other asymmetric encryption
algorithms are also applicable). All messages broadcasted on BC_123456789 are signed using the private-key that is generated
by the phone 1234-56789 during installation; except when broadcasting the public key itself as when the app is first installed on
the phone. The digital signature that ShyChat attaches to each broadcast message is constructed by first generating the SHA-1
digest of the message, then encrypting the digest using the sender’s private key. A potential breach in this scheme is if someone
broadcasts a public key on BC_123456789 before the phone 1234-56789 itself installs the app; this would let that intruder
impersonate the phone 1234-56789, thus a separate verification scheme via SMS is also available for those who are very
cautious. SMS verification may be initiated manually by the ShyChat user of the phone 1234-56789 to assure another ShyChat
user that the phone 1234-56789 is not impersonated. When initiated, the phone 1234-56789 constructs an SMS message that
contains both the SHA-1 digest of the public key of the phone 1234-56789 as well as a randomly generated PIN. The recipient
phone detects such an SMS automatically and matches the digest in it with that of the public key it received previously over
BC_123456789. If matched, the contact 1234-56789 is marked “verified” in the recipient’s contacts list, and the PIN attached to
this verification SMS is sent back in an encrypted message over the channel RCV_123456789 so that the phone 1234-56789
marks the contact recipient of the SMS “verified” as well. This verification scheme assumes that the SMS service itself is
secure.
When the phone 1234-56789 broadcasts its public key over BC_123456789, it attaches to this broadcast message its GCM
registration token. Whoever records the public key of the phone 1234-56789 also records its GCM registration token. This
allows other ShyChat users to manually check the registration status of the phone 1234-56789 with the GCM service; that is, to
check whether or not the user of the phone 1234-56789 phone has uninstalled ShyChat. We refer to this feature as GCM peer
checking. Only through GCM peer checking that the “verified” label attached to a contact may be removed. In other words, if
the phone 1234-566789 uninstalls ShyChat, then re-installs it, another phone that has the contact 1234-56789 marked “verified”
will not accept the new public key (and the new GCM registration token) broadcasted by the phone 1234-56789 except after
manually checking the old registration token of the phone 1234-56789 with the GCM service to detect whether or not the phone
1234-56789 has really uninstalled the old app instance associated with the old registration token. This prevents intruders from
impersonating 1234-56789 after it got verified. We make the design decision that GCM peer checking has to be done manually;
otherwise a spam detection mechanism needs to be implemented as well.
Overall, the process of installing ShyChat on the phone 1234-56789 involves registration with GCM, subscription to
RCV_123456789, and broadcasting over BC_123456789 the public key and the GCM registration token of the phone
1234-56789. Once these steps are done, ShyChat starts enumerating in the background all phone numbers in the contacts list of
the phone 1234-56789, and subscribes to the broadcast channel of each of those contacts. As a result, whenever any of those
contacts installs ShyChat in the future, their public keys (and registration tokens) will be received by the phone 1234-56789
through their broadcast channels. For those contacts who already have ShyChat installed, a handshaking protocol is initiated to
exchange secret keys. Secret keys are used for symmetric encryption where both the source and the destination of a message
use the same secret key to encrypt and decrypt the message. This is more efficient than asymmetric private-key/public-key
encryption in terms of both the processing time and the size of the cipher text. In ShyChat, the handshaking messages used to
exchange secret keys between two phones, before their users exchange any meaningful messages, are themselves encrypted
using asymmetric encryption, in our case RSA. We choose 128-bit AES as our symmetric encryption algorithm. This moderate
choice ensures that an AES secret key, encrypted using RSA, still fits within a single GCM message, while also ensuring that
subsequent user communications, encrypted using this AES key, are secure enough.

III. HANDSHAKING
In this section we elaborate on our handshaking protocol for exchanging secret keys between two ShyChat users, say Alice
and Bob, before they start having any conversations. Although we use human names like Alice and Bob when referring to
phones, all handshaking operations are done automatically and in the background, on behalf of the users. We make the design
decision of using two secret keys for each pair of users communicating with one another. Think of a private conversation
between Alice and Bob as a two-lane road, with messages sent from Alice to Bob being encrypted and decrypted using a secret
key, while those sent from Bob to Alice are encrypted and decrypted using another secret key. This design decision simplifies
the handshaking protocol, specially since secret keys should be updated frequently. Obviously, each of the two users need to
have both secret keys for any meaningful conversation to take place. Our concern is not just to keep the conversation private,
but also to keep the source and the destination of exchanged messages private; that is, a sniffer should not be able to know who
is sending to whom, so long as the GCM service itself is secure.
To see how this works we begin by explaining the structure of messages exchanged between ShyChat users. Each message
begins by an ENCRYPTED flag indicating whether this message is encrypted or not. Unencrypted messages are typically
broadcast messages sent over BC channels; those are usually digitally-signed but never encrypted. Special types of messages
sent over RCV channels may be unencrypted as well; as we see later in this section. In general, if the ENCRYPTED flag at the
beginning of a message is set, then it must be followed by a decryption key identifier indicating which key should be used by
the recipient phone to decrypt this message. A key identifier of 0 indicates that this message was encrypted using the public key
of the recipient phone, as the case during handshaking for example, and thus should be decrypted using the private key of the
recipient phone. Otherwise, a non-zero key identifier indicates that this message was sent from a phone that had already
completed handshaking with the recipient phone. Let the local (recipient) phone be Alice and the remote (sender) phone be Bob.
When the decryption key identifier is non-zero, Alice uses this identifier to lookup her decryption keys table for a secret key to
decrypt this message. The decryption keys table is maintained locally by Alice and contains secret keys generated during
handshaking. Alice uses the decryption secret key associated with Bob’s key identifier to decrypt this message. Once decrypted
and processed, and if a response (e.g., an acknowledgement) is necessary, ShyChat builds a response message and encrypts it.
Alice, just like any other ShyChat user, maintains besides her decryption keys table an encryption keys table, to be used when
sending encrypted messages over RCV channels. Unlike the decryption keys table, the encryption keys table is indexed by
phone numbers of contacts, and contains for each contact either a public key or a secret key. If Bob’s entry in Alice’s encryption
keys table contains a secret key, then it must also contain a remote decryption key identifier to be placed in the header of the
encrypted response sent to Bob. This remote decryption key identifier is the key identifier that Bob will use to lookup his own
decryption keys table for a secret key to decrypt Alice’s response. Having said that, and before we explain our handshaking
protocol itself, we shall also mention that whenever a message sent over a RCV channel is encrypted via a public key, it must
also be digitally signed using the private key of the sender. Digital signature is applied to the message before encryption but is
still excluded from encryption. First thing to be done after such a message is decrypted at the recipient’s side, using the
recipient’s private key, is to check it the way a broadcast message is checked; that is, to extract the sender’s phone number from
the message and use it to lookup the local encryption keys table for the sender’s public key, then use the sender’s public key to
decrypt the digital signature of the message, and compare the resulting digest against a locally generated digest of the decrypted
message.
Here we explain the handshaking protocol itself. Consider the same example of two phones, Alice and Bob. Alice already has
ShyChat installed, while Bob has just installed the app for the first time. Bob begins by broadcasting his public key in a
PUBLIC_KEY message over BC_Bob. If Alice does not have Bob in her contacts list nothing will happen. Otherwise, if Alice
has Bob in her contacts list, Alice will receive Bob’s PUBLIC_KEY broadcast message, will save it in her encryption keys
table, and will respond by sending her own public key to Bob through the channel RCV_Bob in another PUBLIC_KEY
message, with a flag indicating that this is actually a response so as to avoid an infinite loop of public key exchanges. Next,
Alice generates a secret key, saves it in her decryption keys table, obtains a decryption key identifier, and sends both the secret
key and the identifier in an encrypted SECRET_KET message to Bob, informing him that he should use this key and this
identifier whenever he sends encrypted messages to Alice in the future. This SECRET_KEY message is itself encrypted using
Bob’s public key, and thus the decryption key identifier field in the header of the message itself is set to 0, and the message is
digitally signed using Alice’s private key.
If Bob does not have Alice in his contacts list, he will ignore both her PUBLIC_KEY and her SECRET_KEY messages. So
we focus on the case when Alice is in Bob’s contacts list. Bob receives Alice’s PUBLIC_KEY message first, so he creates an
entry for Alice in his encryption keys table, and saves her public key there. Since Alice’s PUBLIC_KEY message has a flag
indicating that it is actually a response, Bob will not take any further steps. Next, Bob receives Alice’s SECRET_KEY message,
so he extracts from it the secret key and the key identifier that were generated by Alice, and saves them in his encryption keys
table, to be the encryption key and the remote decryption key identifier associated with Alice. Now, and only now, Bob marks
Alice “Available” in his contacts list; this means that Bob can initiate a conversation with Alice. However, immediately after
processing Alice’s SECRET_KEY message, Bob starts building his own SECRET_KEY response to Alice; he generates another
secret key, saves it in his decryption keys table, obtains a decryption key identifier, and sends both his key and his identifier in
an encrypted SECRET_KEY message to Alice, informing her that she should use this key and this identifier whenever she sends
encrypted messages to him in the future. Bob’s SECRET_KEY message must have a flag indicating that it is actually a response
so as to avoid an infinite loop of SECRET_KEY exchanges. Also, this SECRET_KEY message is itself encrypted using Alice’s
public key, and thus the decryption key identifier field in the header of the message itself is set to 0, and the message is digitally
signed using Bob’s private key. Finally, Alice receives Bob’s SECRET_KEY message, extracts from it the secret key and the
key identifier that were generated by Bob, and saves them in her encryption keys table, to be the encryption key and the remote
decryption key identifier associated with Bob. Now, and only now, Alice marks Bob “Available” in her contacts list; this means
that she can initiate conversations with Bob.
Notice that message ordering during handshaking matters. Alice’s PUBLIC_KEY message must reach Bob not after her
SECRET_KEY message so that he can check her digital signature. Also, Bob’s SECRET_KEY message must reach Alice not
after any conversation he may initiate with her so that she can encrypt her responses. Although the GCM service always delivers
messages to the destination ISP in the order they are sent, we do not take chances; messages that has to be delivered in order
(e.g., Alice’s PUBLIC_KEY and SECRET_KEY messages) are packed in a single GCM message and unpacked at the
destination; this approach is safer and also more efficient as each GCM invocation costs us an HTTPS POST request. Notice
also that when we process incoming messages; the two operations of updating local data and sending response messages have to
happen atomically; for example, when Alice generates a secret key and sends it to Bob in response to his PUBLIC_KEY
message, we can not tolerate to have one of these two operations succeeds and the other fails. Thus, all automatic responses to
incoming messages are stored locally in the same database where local data updates are performed, and using the same
transaction. If the response messages could not be delivered successfully for whatever reason, e.g. network outage or GCM
service issues, they remain in the local database until ShyChat detects that the communication issue is resolved then they are
sent again.
Now consider the case when Alice is not in Bob’s contacts list at the time when he installs the app, but she gets added to his
contacts list later. ShyChat monitors the user’s local contacts list in the background. Adding a new contact, Alice in our case,
triggers Bob to send his PUBLIC_KEY message automatically to Alice over RCV_Alice. If Alice have not uninstalled and
reinstalled ShyChat since she last received Bob’s PUBLIC_KEY broadcast, Bob’s entries in Alice’s encryption and decryption
key tables are still there; Alice makes sure that Bob’s public key has not changed since she last received his PUBLIC_KEY
message then proceeds with the handshaking protocol using the secret key she generated for Bob before. Otherwise, if Bob’s
public key has changed, indicating that he has uninstalled and reinstalled the app, Alice generates a new secret key for Bob so
that the protocol remains semantically correct. If, after handshaking has completed successfully, either of the two users, say
Alice, removes the other one, Bob, from her contacts list, such event will only mark Bob “deleted” in Alice’s database and Bob
will be informed; however, neither public keys nor secret keys will be affected. Although Alice and Bob will not be able to
initiate conversations with one another until Alice adds Bob back to her contacts list, another round of handshaking will not be
required unless one or both of the two users uninstalls and reinstalls the app.

IV. SHYCHAT USE CASES


ShyChat is a social and messaging app. It provides two main functionalities: anonymous tweets, and anonymous chatting.
Users choose from their contact lists which contacts to befriend. Befriending someone means that you are accepting anonymous
tweets and anonymous chatting from that person, and you are also letting that person realize that you are doing so. Anonymous
tweets are similar to tweets, but they are anonymous; that is, you know that these tweets are from some of your friends but you
do not necessarily know which friends posted which tweets. Anonymous chatting is another feature in ShyChat. One user (the
initiator) picks a nickname and starts a chatting session with another user (the recipient). The user with the nickname may
choose to reveal his/her identity any time. However, not until this chatting session is terminated by the recipient that the initiator
may start a new chatting session using a different nickname. Part of the motivation behind ShyChat is to encourage others to
“break the ice” with you. Hence an important feature in ShyChat is to let those whom you befriend know how many others you
currently befriend. To see it from the other’s perspective, anonymous chatting is no longer anonymous if it is with someone
whose only friend(s) are you. You may choose to unfriend someone in your contacts list, and you may choose to ignore a
chatting session, perhaps for a while; but part of the philosophy behind ShyChat is to not block a nickname. Ignoring a chatting
session is not a stealth event. The other user should realize that. Therefore, another important feature of ShyChat is to let those
involved in a chatting session know whether and when their chat messages are seen by one another.
Consider for example when someone initiates a chatting session with you using a catchy nickname and says “I love you.”
Suppose you are very curious to know his/her identity. You may either enter into a flirt-ignore teasing cycle with that person, or
you may tweet asking all those befriending you to initiate anonymous chatting with you and reveal their identities immediately
so that whoever remains is the guy in question. However, one should keep in mind that befriending is an asymmetric
relationship. Not all those whom you befriend will read your tweet since not all of them necessarily befriend you. Also, not all
those who read your tweet can initiate chatting with you as some of them may not have been befriended by you. Fig. 1 shows
two snapshots of ShyChat. One snapshot (left) shows a typical anonymous chatting session, while the other one (right) shows
the tweets stream in ShyChat, which we refer to as broadcast.
We make the design decision not to provide a “retweet” feature in ShyChat. Retweeting is similar to email forwarding but
for microblogging apps. Our assessment is that retweeting suits non-anonymous microblogging apps like Twitter where users
know who wrote the posts they retweet, and who retweeted the posts they read. For anonymous microblogging such feature
could help spread rumors and does not serve the “break the ice” purpose for which ShyChat was designed.

V. DEMO
ShyChat is available for free on Google’s play store. In this demo, the user may test the various use cases supported by
ShyChat using two or more Android phones having Google Play APIs installed and internet connection available. Besides the
typical day-to-day use cases mentioned in Section IV, users may also try joining and leaving ShyChat’s social network in
different orders and examine how ShyChat handles corner cases robustly.

You might also like