Mesibo End-to-End Encryption APIs

Estimated reading time: 11 minutes

mesibo’s end-to-end encryption (E2EE) algorithm ensures that messages and calls between your users are secure and no one can read or listen to them, not even mesibo or your app (if you are using mesibo on-premise). mesibo end-to-end encryption (E2EE) algorithm encrypts each message with a different encryption key so that it is difficult to intercept the communication. mesibo also has a special man-in-the-middle (MITM) protection mode for extra sensitive communication.

mesibo’s end-to-end encryption algorithm is an improvement over existing protocols, namely OTR, SCIMP, and Open Whisper System (used by WhatsApp, Signal, etc), and it is currently the strongest end-to-end encryption protocol in the market.

mesibo’s end-to-end encryption protocol was initially based on Signal’s protocol and then improved considerable with many enhancements, for example,

  • Serverless, Peer-to-peer Protocol
  • Better Ciphers (AES-GCM, Chacha20-Ply1305) and multi-cipher mode
  • Complete protection against the man-in-the-middle attack
  • Improved X3DH and Double Ratchet Algorithm
  • Improved Fingerprints

You can read about improvements in detail here.

E2EE is currently available for Android, IOS, C++, and Python only. It will be available for JavaScript soon. Note that, even without E2EE, all the communication is secure and encrypted with TLS. Also, the on-premise retention and multi-device sync feature can not work with E2EE.

Enabling End-to-End Encryption

You can enable end-to-end encryption with just one line of code. Once you enable it, your app will automatically become the most secure messaging and calling app globally. Due to the growing concern for privacy, there are no reasons to not enable end-to-end encryption in your apps.

In Java and Kotlin,


In Objective-C,

[[MesiboInstance e2ee] enable:YES];

In Swift,


You don’t need to do anything other than to enable it. However, if you need more control, you can use the E2EE APIs described below.

Mesibo End-to-End Encryption API

There are only two classes to configure mesibo E2EE:


MesiboEndToEndEncryption is a global class to manage global and per-user E2EE configurations. Mesibo creates an instance of the class which you can access by calling Mesibo.e2ee() function as shown above.


MesiboProfileEndToEndEncryption is a class to manage a user-specific E2EE configurations. MesiboProfile creates an instance of the class which you can access by calling MesiboProfile.e2ee() function.

In addition, there are two mesibo e2ee listeners that you can implement to get updates on various E2EE events, for example, E2EE activated or deactivated by the peer, peer identity changed, peer identity verification failed, or any suspicious attempts.

  • Mesibo_onEndToEndEncryption, a global listener which will be called for all E2EE events.
  • MesiboProfile_onEndToEndEncryption, a profile-specific listener which will be called only for E2EE events for a user.

In the following sections, we will describe MesiboEndToEndEncryption APIs. The MesiboProfileEndToEndEncryption APIs are a subset of MesiboEndToEndEncryption and have the same API signature except that you do not have to pass the user address.

Common APIs

Setting E2EE Level

You can set e2ee level from 1 to 10 and the secure-only mode by calling setLevel method of MesiboEndToEndEncryption.

void setLevel(int level);

setLevel takes the following parameters:

Parameter Description
level Encryption level (1-10), 1 is the higest



E2EE-Only mode

By default, users without e2ee can communicate with e2ee-enabled users. This is recommended since some of your users might be using older APIs that do not support E2EE. However, you can override and enable the E2EE-only mode to disable communication with all non-e2ee users.

void secureOnly(boolean enable);

setLevel takes the following parameters:

Parameter Description
enable Enable or Disable E2EE mode



Get Status

You can get the E2EE status for any user by calling one of these APIs

int getStatus(address);
boolean isActive(address);

The status can be one of the following. You can also implement E2EE listeners to get notified of status change instantly:

Status Description
MESIBO_E2ESTATUS_IDENTITYCHANGED E2EE is Active but user identify has changed
MESIBO_E2ESTATUS_FAILED E2EE key negotiation failed
MESIBO_E2ESTATUS_IDENTITYFAILED E2EE identity verification failed
MESIBO_E2ESTATUS_SUSPICIOUS E2EE is not active. Suspicious attempts detected

Both APIs take the following parameters:

Parameter Description
address The remote user address


boolean e2ee.isActive("user-1");

Getting Fingerprints

A fingerprint allows you to verify that you are indeed communicating with the intended person and no one is watching your conversations. There are two types of fingerprints

  • Communication Fingerprint - it’s a unique and identical fingerprint between you and the peer. By comparing this one fingerprint, both of you can be certain about untampered communication.

  • User Fingerprint - it’s a unique fingerprint of the user. It is not the public key.

We recommend using Communication Fingerprint.

String getFingerprint(String address);
String getUserFingerprint(String address);

Both functions take the following parameters:

Parameter Description
address The remote user address


String fingerprint = e2ee.getFingerprint("user1");

You should check active status before calling fingerprint APIs.

Cryptography APIs

mesibo automatically sets optimized cryptography configuration and hence you don’t need to use any of these APIs unless you have special needs.

Setting Supported and Preferred Ciphers

mesibo supports using multiple ciphers simultaneously to make interception difficult. By default, all the ciphers are enabled. mesibo prefers to use CTR-based and AEAD (authenticated encryption with associated data) ciphers and the AES-GCM is the default preferred cipher. You can change the supported and preferred ciphers by calling setCiphers method of MesiboEndToEndEncryption.

Note that, we do not recommend using CBC and non-AEAD ciphers though it is used by some implementations like Signal. However, we do not restrict if you like to use them.

  • Chacha20-Poly1305 (MESIBO_E2ECIPHER_CHACHAPOLY1305) - Recommended
void setCiphers(long supported, long preferred);

setCiphers takes the following parameters:

Parameter Description
supported Logical OR combination of all the ciphers to be supported
preferred Logical OR combination of all the preferred ciphers



Setting Authentication Tag Length

mesibo generates an authentication tag which will be sent along with the message. The length of the tag is determined by the size of the message and it is optimized based on research papers and also NIST recommendations. However, you can change the tag length if requires. The valid tag lengths are 4, 6, 8, 10, 12, 14, and 16 bytes.

int setAuthenticationTaglen(int len);

setAuthenticationTaglen takes the following parameters:

Parameter Description
len Tag length. Valid lengths are 4, 6, 8, 10, 12, 14, and 16 bytes. Set 0 for auto length.



Setting Additional Authenticated Data (AAD)

Additional authenticated data (AAD) is any additional data that you pass to authentication algorithms. It could be anything random depending on your application. It has no contribution towards encryption and AAD is only used as an integrity check. The AAD data must be no larger than 64 KBytes. mesibo already adds AAD data and hence use of this API is OPTIONAL unless you have special needs to use it.

boolean setAuthenticationData(String aad, int len);

setAuthenticationData takes the following parameters:

Parameter Description
address The remote user address
aad Additional authenticated data


e2ee.setAuthenticationData("user-1", "some aad data");

Man-in-the-middle Protection APIs

It is generally not necessary to configure these options for casual chat. The default end-to-end encryption provides best-in-class security. However, if you are worried about eavesdropping, you can use a secret password, or install the public certificate of the peer. They are included in the per-message encryption process, and these out-of-the-band methods make it nearly impossible for anyone to intercept your communication.

Setting a Password

You can set a password that is included in the encryption process (KDF). The peer needs to use the same password to decrypt the messages. Setting a password can be very effective against a man-in-the-middle attack. Refer to the article link above for the description.

void setPassword(String address, String password);

setPassword takes the following parameters:

Parameter Description
address The remote user address
password Password


e2ee.setPassword("user1", "some password");

Creating a Private Certificate

mesibo automatically generates a private certificate for you which safely remains on your device only. However, if you prefer to use your custom certificate, you can load it here.

To load a custom private certificate, you need to supply PKCS#12 file with Curve25519 private and public keys. Your certificate MUST contain UID=’your mesibo address’ and CN=’mesibo’ for validation. You must also specify O=’your app name’.

You can use any tools for generating a private certificate. Below is an OpenSSL example,

$ openssl req -nodes -new -x509 -newkey ed25519 -keyout my.key -out -days 3652 -subj '/CN=mesibo/O=myapp/UID=MyAddress'
$ openssl pkcs12 -export -in -inkey my.key -out my.p12

Do not set password when exporting.

BOOL setPrivateCertificate(String filename);

setPrivateCertificate takes the following parameters:

Parameter Description
filename The PKCS#12 filename with .p12 or .pfx extension



Exporting Public Certificate

Your public certificate gets safely transmitted by mesibo to your peers without any manual interventions. However, if you suspect any man-in-the-middle attack (which is highly unlikely), you can export and share your public certificate with your peers by other means.

String getPublicCertificate();

getPublicCertificate does not take any parameters. It returns the file path of the exported certificate.


String filePath = e2ee.getPublicCertificate();

Loading Public Certificate of a Peer

As mentioned in the previous section, public certificates are exchanged automatically without any manual interventions. However, if you suspect any man-in-the-middle attack, you can load the exported certificate by your peer.

BOOL setPeerCertificate(String address, String filename);

setPeerCertificate takes the following parameters:

Parameter Description
address The remote user address
filename Exported certificate with .pub or .pem extension


encryption, end-to-end encryption, AES-GCM, Chacha20-Poly1305, Signal, AES-CBC