Secret chats, end-to-end encryption
OBMeet End-to-end encryption (E2EE) is a system of communication where only the communicating users can read the messages. In principle, it prevents potential eavesdroppers – including telecom providers, Internet providers, and even the provider of the communication service – from being able to access the cryptographic keys needed to decrypt the conversation. The systems are designed to defeat any attempts at surveillance or tampering because no third parties can decipher the data being communicated or stored..
* This is embedded into an outer layer of our cloud encrytion and thereafter into it's transport protocol (HTTPS, TCP.)
In OBMeet end-to-end encryption (E2EE) system, encryption keys are used between communicating parties. To achieve this goal, E2EE systems can encrypt data using a pre-arranged string of symbols, called a pre-shared secret (PGP), or a one-time secret derived from such a pre-shared secret (DUKPT). Our secret key is on the spot using Diffie-Hellman key exchange (OTR).
Modern Encryption Usage
Our end-to-end encryption include PGP, GnuPG, Protonmail, Mailfence, S/MIME, Inky, Tutanota or pEp for email; OTR, iMessage, Threema, and for instant messaging; ZRTP and for telephony; TETRA
End-to-end encryption is regarded as safer because it reduces the number of parties who might be able to interfere or break the encryption. In the case of instant messaging, users may use a third party client (e.g., Pidgin) to implement an end-to-end encryption scheme (e.g. OTR) over an otherwise non-E2EE protocol.
Our encrypted backup and file sharing services provide client-side encryption.
Our most end-to-end encryption protocols include some form of endpoint authentication specifically to prevent MITM attacks.
For example, one could rely on certification authorities or a web of trust. An alternative technique is to
generate cryptographic hashes (fingerprints) based on the communicating users’ public keys or shared secret keys.
The parties compare their fingerprints using an outside (out-of-band) communication channel that guarantees integrity
and authenticity of communication (but not necessarily secrecy), before starting their conversation.
If the fingerprints match, there is in theory, no man in the middle.
When displayed for human inspection, fingerprints are usually encoded into hexadecimal strings. These strings are then formatted into groups of characters for readability. For example, a 128-bit MD5 fingerprint would be displayed as follows:
Sending and Receiving Messages in a Secret Chat
Serialization and Encryption of Outgoing Messages
A TL object of type DecryptedMessage is created and contains the message in plain text. For backward compatibility, the object must be wrapped in the constructor decryptedMessageLayer with an indication of the supported layer (starting with 8).
The TL-Schema for end-to-end encrypted messages contents is represented here ».
The resulting construct is serialized as an array of bytes using generic TL rules. The resulting array is padded at the top with 4 bytes of the array length not counting these 4 bytes.
A message key, msg_key, is computed as the 128 low-order bits of the SHA1 of the data obtained in the previous step.
The byte array is padded with random data until its length is divisible by 16 bytes.
An AES key and an initialization vector are computed ( key is the shared key obtained during Key Generation, x = 0 ):
- sha1_a = SHA1 (msg_key + substr (key, x, 32));
- sha1_b = SHA1 (substr (key, 32+x, 16) + msg_key + substr (key, 48+x, 16));
- sha1_с = SHA1 (substr (key, 64+x, 32) + msg_key);
- sha1_d = SHA1 (msg_key + substr (key, 96+x, 32));
- aes_key = substr (sha1_a, 0, 8) + substr (sha1_b, 8, 12) + substr (sha1_c, 4, 12);
- aes_iv = substr (sha1_a, 8, 12) + substr (sha1_b, 0, 8) + substr (sha1_c, 16, 4) + substr (sha1_d, 0, 8);
Data is encrypted with a 256-bit key, aes_key, and a 256-bit initialization vector, aes-iv, using AES-256 encryption with infinite garble extension (IGE). Encryption key fingerprint key_fingerprint and the message key msg_key are added at the top of the resulting byte array.
Encrypted data is embedded into a messages.sendEncrypted API call and passed to OBMeet server for delivery to the other party of the Secret Chat..
Decrypting an Incoming MessageThe steps above are performed in reverse order.
When an encrypted message is received, you must check that msg_key is in fact equal to the 128 low-order bits of the SHA1 hash of the decrypted message.
If the message layer is greater than the one supported by the client, the user must be notified that the client version is out of date and prompted to update.
Sending Encrypted FilesAll files sent to secret chats are encrypted with one-time keys that are in no way related to the chat’s shared key. Before an encrypted file is sent, it is assumed that the encrypted file’s address will be attached to the outside of an encrypted message using the file parameter of the messages.sendEncryptedFile method and that the key for direct decryption will be sent in the body of the message (the key parameter in the constructors decryptedMessageMediaPhoto, decryptedMessageMediaVideo and decryptedMessageMediaFile.
Prior to a file being sent to a secret chat, 2 random 256-bit numbers are computed which will serve as the AES key and initialization vector used to encrypt the file. AES-256 encryption with infinite garble extension (IGE) is used in like manner.
The key fingerprint is computed as follows:
- digest = md5(key + iv)
- fingerprint = substr(digest, 0, 4) XOR substr(digest, 4, 4)
A subsequent call to messages.sendEncryptedFile will assign an identifier to the stored file and send the address together with the message. The recipient will receive an update with encryptedMessage, and the file parameter will contain file information.
Incoming and outgoing encrypted files can be forwarded to other secret chats using the constructor inputEncryptedFile to avoid saving the same content on the server twice.