After a Tanker session has been started, it can be used to encrypt and decrypt data.

In this section, we'll see how to use the encryption APIs to protect textual data (e.g pieces of text, fields of database records, json payloads).

The encryption of binary resources of any size (e.g. files, documents, photos, videos) is covered here.

Encrypting text

To encrypt a piece of textual data, you need to call encrypt():

byte[] clearData = myData;
byte[] encryptedData = tanker.encrypt(clearData, null).get();

NSData* clearData = myData;
[self.tanker encrypt:clearData
   completionHandler:^(NSData* encryptedData, NSError* err) {
                       if (err == nil) {
                         // handle encrypted data
                       }
                     }];

const clearText = "This is a secret message";
const encryptedData = await tanker.encrypt(clearText);

In case the rest of your application cannot deal with Uint8Array, you can use the toBase64() utility function:

import { toBase64 } from '@tanker/client-browser';

const clearText = "This is a secret message";
const encryptedData = await tanker.encrypt(clearText);
const encryptedText = toBase64(encryptedData);

clear_text = 'This is a secret message'
encrypted_text = tanker.encrypt_utf8(clear_text)

Note

Please note that Tanker does not transfer nor store the encrypted data. For it to be available to your users later and across devices, you need to store it yourself.

Tanker does not expose encryption keys. They will automatically be accessible to the users with whom the data is shared.

Sharing

By default, encrypt() ensures that a user's encrypted data can only be decrypted on all devices of this user. No one else can decrypt() those data.

You can specify additional recipients by providing their Tanker public identity to encrypt() options:

// Ask the application server for Bob and Charlie's public identities
String[] publicIdentities = app.getPublicIdentities(new String[]{"bob-id", "charlie-id"});
EncryptionOptions options = new EncryptionOptions().shareWithUsers(publicIdentities);
byte[] clearData = myData;
byte[] encryptedData = tanker.encrypt(clearData, options).get();

NSData* clearData = myData;
NSArray<NSString*>* identities = [self.app getPublicIdentities:@[@"bob-id", @"charlie-id"]];
TKREncryptionOptions* encryptionOptions = [TKREncryptionOptions options];
encryptionOptions.shareWithUsers = identities;

[self.tanker encryptData:clearData,
                 options:encryptionOptions,
       completionHandler:^(NSData* encryptedData, NSError* err) {
                           if (err == nil) {
                             // handle encrypted data
                           }
                         }];

// Ask the application server for Bob and Charlie's public identities
const publicIdentities = await app.getPublicIdentities(['bob-id', 'charlie-id']);
const encryptedData = await tanker.encrypt(clearText, { shareWithUsers: publicIdentities });

# Ask the application server for Bob and Charlie's public identities
public_identities = app.fetch_public_identities(['bob-id', 'charlie-id'])
encryption_options = Tanker::EncryptionOptions.new(share_with_users: public_identities)
encrypted_data = tanker.encrypt_utf8('Secret message', encryption_options)

This will allow Bob and Charlie, as well as Alice, to decrypt the encrypted data.

It is also possible to share data with user groups. See the groups guide for more information.

Postponing the share operation

Alternatively, if the recipients are not known when encrypt() is called, or if you need to share several resources at once, you can call share() with a list of resource IDs and a list of recipients.

byte[] clearData = myData;
byte[] encryptedData = tanker.encrypt(clearData).get();
String resourceId = tanker.getResourceId(encryptedData);
String[] publicIdentities = app.getPublicIdentities(new String[]{"bob-id", "charlie-id"});
SharingOptions options = new SharingOptions().shareWithUsers(publicIdentities);
tanker.share(new String[]{resourceId}, options).get();

NSData* clearData = myData;
[self.tanker encryptData:clearData
                 options:encryptionOptions
       completionHandler:^(NSData* encryptedData, NSError* err) {
   NSArray<NSString*>* identities = [self.app getPublicIdentities:@[@"bob-id", @"charlie-id"]];

   TKRSharingOptions* sharingOptions = [TKRSharingOptions options];
   sharingOptions.shareWithUsers = identities;

   NSString* resourceID = [self.tanker resourceIDOfEncryptedData:encryptedData error:&err];
   if (err == nil) {
     [self.tanker shareResourcesIDs:@[resourceID]
                            options:sharingOptions
                  completionHandler:^(NSError* err) {
                    if (err != nil) {
                      // handle error
                    }
                  }];
   }
}];

const encryptedData = await tanker.encrypt(clearText);
const resourceId = await tanker.getResourceId(encryptedData);
const publicIdentities = await app.getPublicIdentities(['bob-id', 'charlie-id']);
const options = { shareWithUsers: publicIdentities };
await tanker.share([resourceId], options);

public_identities = app.fetch_public_identities(['bob-id', 'charlie-id'])
encrypted_data = tanker.encrypt_utf8('Secret message')
resource_id = tanker.get_resource_id(encrypted_data)
sharing_options = Tanker::SharingOptions.new(share_with_users: public_identities)
tanker.share([resource_id], sharing_options)

As for simple encryption, Tanker never transfers nor stores the encrypted data. You need to take care of sending it to Bob and Charlie.

Decrypting

To decrypt some encrypted data, simply give it to decrypt(). It will work the same whether the content was encrypted by the current user, or shared with them.

decrypt() will throw an error if the user does not have access to this data (i.e. if the data was not shared with them).

byte[] encryptedData = myData;
byte[] clearData = tanker.decrypt(encryptedData, null).get();

NSData* encryptedData = myData;
[self.tanker decryptData:encryptedData
       completionHandler:^(NSData* decryptedData, NSError* err) {
                           if (err == nil) {
                             // handle decrypted data
                           }
                         }];

const clearText = await tanker.decrypt(encryptedData);

Note that if you used toBase64() as mentioned in the previous section, you should convert encrypted text to binary data first using fromBase64():

import { fromBase64  } from '@tanker/client-browser';

const encryptedData = fromBase64(encryptedText);
const clearText = await tanker.decrypt(encryptedData);

clear_text = tanker.decrypt_utf8(encrypted_text)