mirror of
https://github.com/amnesica/KryptEY.git
synced 2024-10-01 01:05:58 -04:00
113 lines
7.8 KiB
Markdown
113 lines
7.8 KiB
Markdown
# KryptEY
|
||
|
||
KryptEY was created by [mellitopia](https://github.com/mellitopia)
|
||
and [amnesica](https://github.com/amnesica).
|
||
|
||
We implemented a stand alone android keyboard, KryptEY, which enables E2EE encryption of single
|
||
messages on any Android messenger. It is based on
|
||
the [Simple Keyboard](https://github.com/rkkr/simple-keyboard). The Android version of
|
||
the [Signal Protocol](https://mvnrepository.com/artifact/org.signal/libsignal-android) is used for
|
||
the E2EE functionality.
|
||
|
||
The keyboard provides the functionality to encrypt and decrypt messages, is independent of a
|
||
messenger app and does not require a server for the key exchange. The keyboard includes a separate
|
||
text field for entering the message that is to be encrypted. After selecting the receiver, the
|
||
message is sent to the text field of the used messenger and then sent to the chat partner as usual.
|
||
The chat partner copies the message to the clipboard, the application recognises the KryptEY message
|
||
as well as the sender and offers the option to decrypt the ciphertext message. The decrypted message
|
||
is displayed in the KryptEY text field and saved in the message history. Further, chat partners can
|
||
be created and deleted through the application and their security number can be verified by
|
||
comparing it on both end devices. Encrypted and decrypted messages are stored in a message history
|
||
for later viewing and there is a Q&A section that helps with questions about the keyboard and its
|
||
functionalities.
|
||
|
||
The elliptic curve X25519 with SHA-512 is used in the X3DH Key Agreement Protocol from the applied
|
||
Signal library. The hash function SHA-256 is used for the various chains and AES-256 with CBC (
|
||
Pkcs#7) is used for the encryption of the messages. SHA-512 is also used to generate the
|
||
fingerprint, the representation of the public key used for encryption.
|
||
|
||
## Initialization
|
||
|
||
After installing the app, the Signal Protocol is initialised on the device. For this purpose,
|
||
a `SignalProtocolAddress` consisting of a randomised UUID and an arbitrary device id is created.
|
||
Further, an identity key, two one-time prekeys and a signed prekey are created. From this
|
||
information, various stores are created to man- age the protocol: the `IdentityKeyStore`
|
||
, `PreKeyMetadataStore`, `PreKeyStore`, `SenderKeyStore`, `SessionStore`, `SignalProtcolStore`, and
|
||
the `SignedPreKeyStore`. All protocol information is stored serialised in the application’s
|
||
SharedPreferences. The Jackson library is used for this purpose. All the information together forms
|
||
an account on the device, with the `SignalProtocolAddress` identifying the user.
|
||
|
||
In addition, there are four different message types in KryptEY for exchanging keys and ciphertext
|
||
messages between chat partners.
|
||
|
||
1. `PreKeyResponse`: to send the `PreKeyBundle` (Invite message)
|
||
2. `PreKeySignalMessage`: to send a ciphertext and `PreKeyBundle` after establishing the session on
|
||
one’s side.
|
||
3. `SignalMessage`: to send a ciphertext
|
||
4. `PreKeyResponse`+`SignalMessage`: to send a ciphertext with new `PreKeyBundle` information to
|
||
update the session
|
||
|
||
## Session Establishment and Key Management
|
||
|
||
To exchange messages, a session must first be initialised on both end devices. If Bob wants to
|
||
communicate with Alice, Bob needs Alice’s `PreKeyBundle` to establish the session on his side. Alice
|
||
sends this via an invite message, which contains her `PreKeyBundle` data (`PreKeyResponse`). This
|
||
allows Bob to add Alice as a contact within the keyboard and establish a session on his side. Bob
|
||
can now send an initial encrypted message to Alice. Since Alice has not yet initialised a session
|
||
with Bob, this message is a `PreKeySignalMessage` and contains additional information besides the
|
||
actual ciphertext message so that Alice can establish a session with Bob. After Alice has also added
|
||
Bob as a contact and created a session, she can now decrypt the message Bob sent. At this point,
|
||
both parties have established a session and can send messages to each other. These messages
|
||
are `SignalMessages`.
|
||
|
||
The one-time prekeys used to establish the sessions are renewed after each use, while the identity
|
||
key is never renewed. After 30 days the signed prekeys are rotated. The old signed prekey is deleted
|
||
after 2 days. After such rotation, an updated `PreKeyBundle` is sent together with an encrypted
|
||
message with which the receiver, e.g. Bob, can update his session with Alice (`PreKeyResponse`
|
||
+`SignalMessage`). This combination of messages eliminates the need for a separate reading of the
|
||
renewed KeyBundle information. For the user, the message appears like a normal `SignalMessage`. The
|
||
session management with the manually created `PreKeyResponse` is necessary, because no server is
|
||
used for the exchange of the `PreKeyBundles`.
|
||
|
||
In addition to the `PreKeySignalMessage` and `SignalMessage`, which are also used by the Signal app,
|
||
KryptEY uses the `PreKeyResponse` and `PreKeyResponse`+`SignalMessage`. As previously mentioned,
|
||
these are necessary to guarantee the Signal Protocol without the use of a server. Further, in the
|
||
Signal app 100 one-time prekeys are created, while in KryptEY only 2 one-time prekeys are created.
|
||
These one-time prekeys are replaced after each use, which eliminates the need for time-consuming key
|
||
management of 100 one-time prekeys. Also, unlike Signal, KryptEY does not use telephone numbers to
|
||
identify users. Instead, randomised UUIDs are used. This could contribute to an increase of the
|
||
privacy of the users, since no telephone numbers are used to identify the users.tween chat partners.
|
||
|
||
## MessageEnvelope and Message Encoding
|
||
|
||
To send a message, all information is collected in a `MessageEnvelope` and then sent as plain JSON
|
||
or hidden in a decoy message. Depending on the message type, this envelope contains
|
||
the `PreKeyResponse`, the `CipherTextMessage` (`PreKeySignalMessage` or `SignalMessage`) as a byte
|
||
array, the type of the `CipherTextMessage` (`PreKeySignalMessage` or `SignalMessage`), a timestamp
|
||
and the `SignalProtocolAddress`.
|
||
|
||
There are two different encoding modes in KryptEY, raw mode and fairytale mode. Messages can be sent
|
||
as a JSON array (raw mode) or hidden in a decoy message (fairytale mode) to make the conversation
|
||
look inconspicuous. In the latter, the encrypted message is hidden in invisible, non-printable
|
||
Unicode characters. To keep the message size as small as possible, the JSON is minified, i.e. all
|
||
spaces and paragraphs are removed and the key values of the JSON are replaced by abbreviated key
|
||
values, e.g. ”preKeyResponse” becomes ”pR”. After that, the string is compressed with GZIP and
|
||
converted into a binary string. When converting to invisible Unicode characters, 4 bits are always
|
||
mapped to an invisible Unicode character like U+200C (ZERO WIDTH NON-JOINER). There are 16 invisible
|
||
Unicode characters to choose from, covering all combinations from 0000-1111. The invisible Unicode
|
||
string is then placed after an arbitrary sentence from one of the two available
|
||
fairytales [Cinderella](https://www.cs.cmu.edu/∼spok/grimmtmp/016.txt)
|
||
and [Rapunzel](https://www.cs.cmu.edu/∼spok/grimmtmp/009.txt) and can be sent to the application.
|
||
After receiving, the invisible Unicode characters are extracted from the message, converted to a
|
||
binary string, decompressed, and deminified. Then the message can be read by the app. The invisible
|
||
characters are included in the transmitted messages, which can cause problems in some messengers,
|
||
unfortunately (see Limitations in the README).
|
||
|
||
## Additional Information
|
||
|
||
The keyboard only needs the ”VIBRATE” permission to enable vibration after key press. Unlike
|
||
the [Android Open Source Project keyboard](https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/refs/heads/master/java/AndroidManifest.xml)
|
||
, the application does not require any sensitive permissions such as access to external storage or
|
||
contacts. Internet access is also not needed. At least Android 8.0 (API 26) is required and the
|
||
application has been licensed with GPL-3.0.
|