Encryption and decryption
Encryption can be performed by either the user or the group object. Additionally, a new symmetric key can be generated for encryption purposes for either a user or a group.
Encrypt for a group
When encrypting content for a group, the content will be encrypted using the group's current key. In the event of a key rotation, the new group key will be used to encrypt new content, while the previous key can still be used to decrypt previously encrypted content.
TIP
Sentc will handle key management for you, determining which key should be used for encryption and which key should be used for decryption.
Encrypt for a user
When encrypting content for a user, the content is encrypted using the user's public key. However, it is important to note that public/private key encryption may not be suitable for handling large amounts of data. To address this, best practice is to use a symmetric key to encrypt the content, and then encrypt the symmetric key with the user's public key (as with groups).
When encrypting content for a user, the reply user ID is required.
TIP
We highly recommend creating a group even for one-on-one user communication. This allows the user who encrypts the data to also decrypt it later without any additional configuration. To achieve this, simply auto-invite the other user and use the "stop invite" feature for this group.
For more information on auto-invite functionality, please see the auto invite. section.
Encrypt raw data
Raw data are bytes.
For javascript, Uint8Arrays are used for raw data.
For a group:
const encrypted = await group.encrypt(new Uint8Array([1,1,1,1]));
For a user:
const encrypted = await user.encrypt(new Uint8Array([1,1,1,1]), "<reply_id>");
Example to load a file as Uint8Array with the file reader:
function fileParse(file: Blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = (e) => {
//@ts-ignore -> is read as array buffer
resolve(e.target.result);
};
reader.onerror = (e) => {
reject(e);
};
reader.readAsArrayBuffer(file);
});
}
//Blob can be a javascript file element too
async function fileLoadingAndEncryption(file: Blob) {
const uint8arrayFile = await fileParse(file);
//get the group obj from outside of the function
const encryptedFile = await group.encrypt(uint8arrayFile);
//do domething with the encrypted file
}
TIP
For file upload you can also use the sentc file handling
For Flutter, Uint8List are used for raw data.
For a group:
final encrypted = await group.encrypt(Uint8List.fromList(elements));
For a user:
final encrypted = await user.encrypt(Uint8List.fromList(elements), "<reply_id>");
TIP
For file upload you can also use the sentc file handling
Raw data are bytes (&[u8]).
For a group:
use sentc::keys::StdGroup;
fn example(group: &StdGroup, data: &[u8])
{
let encrypted = group.encrypt_sync(data).unwrap();
}
For a user:
use sentc::keys::StdUser;
fn example(user: &StdUser, data: &[u8])
{
let encrypted = user.encrypt_sync(data, user_public_key, false).unwrap();
}
Decrypt raw data
For groups this is the same way around like encrypting data. Every group member can encrypt the data.
For javascript, Uint8Arrays are used for raw data. The encrypted data should be a Uint8Array too.
const decrypted = await group.decrypt(encrypted);
For flutter, Uint8List are used for raw data. The encrypted data should be a Uint8List too.
final decrypted = await group.decrypt(encrypted);
Raw data are bytes (&[u8]).
use sentc::keys::StdGroup;
fn example(group: &StdGroup, data: &[u8])
{
let decrypted = group.decrypt_sync(data, None).unwrap();
}
For user this is a little more complicated. Only the user which user id was used in encrypt can decrypt the content.
But the right key is automatically fetched by sentc.
For javascript, Uint8Arrays are used for raw data. The encrypted data should be a Uint8Array too.
const decrypted = await user.decrypt(encrypted);
For flutter, Uint8List are used for raw data. The encrypted data should be a Uint8List too.
final decrypted = await user.decrypt(encrypted);
use sentc::keys::StdUser;
fn example(user: &StdUser, encrypted: &[u8])
{
let decrypted = user.decrypt_sync(encrypted, None).unwrap();
}
Encrypt strings
Encrypting strings is a special case, as it requires converting the text to bytes using an UTF-8 reader before encryption.
To simplify this process, Sentc offers string encryption functions that handle this conversion for you.
For a group:
const encrypted = await group.encryptString("hello there!");
For a user:
const encrypted = await user.encryptString("hello there!", "<reply_id>");
For a group:
final encrypted = await group.encryptString("hello there!");
For a user:
final encrypted = await user.encryptString("hello there!", "<reply_id>");
use sentc::keys::StdGroup;
fn example(group: &StdGroup, data: &str)
{
let encrypted = group.encrypt_string_sync(data).unwrap();
}
For user:
use sentc::keys::StdUser;
fn example(user: &StdUser, data: &str)
{
let encrypted = user.encrypt_string_sync(data, user_public_key, false).unwrap();
}
Decrypt strings
The same as decrypt raw data but this time with a string as encrypted data.
The encrypted strings are strings too.
For a group:
const decrypted = await group.decryptString(encrypted);
For a user:
const decrypted = await user.decryptString(encrypted);
The encrypted strings are strings too.
For a group:
final decrypted = await group.decryptString(encrypted);
For a user:
final decrypted = await user.decryptString(encrypted);
use sentc::keys::StdGroup;
fn example(group: &StdGroup, data: &str)
{
let decrypted = group.decrypt_string_sync(data, None).unwrap();
}
For user:
use sentc::keys::StdUser;
fn example(user: &StdUser, encrypted: &str)
{
let decrypted = user.decrypt_string_sync(encrypted, None).unwrap();
}
Sign and verify the encrypted data
Sentc offers the ability to sign data after encryption and verify data before decryption. This ensures the authenticity of the encrypted data and protects against potential tampering.
Sign
For sign, the newest sign key of the user is used.
For a group:
//just set sign to true
const encrypted = await group.encryptString("hello there!", true);
For a user:
const encrypted = await user.encryptString("hello there!", "<reply_id>", true);
//just set sign to true
final encrypted = await group.encryptString("hello there!", true);
For a user:
final encrypted = await user.encryptString("hello there!", "<reply_id>", true);
For the rust version you need to get the sign key from the user for groups.
use sentc::keys::StdGroup;
fn example(group: &StdGroup, data: &str)
{
let encrypted = group.encrypt_string_with_sign_sync(data, user_sign_key).unwrap();
}
For user:
use sentc::keys::StdUser;
fn example(user: &StdUser, data: &str)
{
let encrypted = user.encrypt_string_sync(data, user_public_key, true).unwrap();
}
Verify
For verify, the right verify key is fetched, but you need to save the id of the user who encrypted the content.
For a group:
//just set sign to true
const decrypted = await group.decryptString(encrypted, true, "<user_id>");
For a user:
const decrypted = await user.decryptString(encrypted, true, "<user_id>");
final decrypted = await group.decryptString(encrypted, true, "<user_id>");
For a user:
final decrypted = await user.decryptString(encrypted, true, "<user_id>");
For verify, the right verify key needs to be fetched first.
use sentc::keys::StdGroup;
fn example(group: &StdGroup, data: &str)
{
let decrypted = group.decrypt_string_sync(data, Some(user_verify_key)).unwrap();
}
For user:
use sentc::keys::StdUser;
fn example(user: &StdUser, encrypted: &str)
{
let decrypted = user.decrypt_string_sync(encrypted, Some(user_verify_key)).unwrap();
}