Skip to content

XChaChaSecretBoxCipher

Tom Auger edited this page May 25, 2018 · 1 revision

Technical Details

Parameter Value
Encryption Algorithm XChaCha20
Authentication Algorithm Poly1305-MAC
Key Size 32 bytes
Nonce Size 24 bytes
Max Message Size 2^64-1 bytes

Description

The XChaChaSecretBoxCipher class wraps the crypto_secretbox_xchacha20poly1305_* functions provided in libsodium. This is based on the crypto_secretbox construction in the NaCl crypto library, but using XChaCha20 with Poly1305 for the MAC.

Example

The following example demonstrates how to encrypt/decrypt a single message:

Encryption

using (var key = XChaChaKey.Generate())
{
    var secretBoxCipher = new XChaChaSecretBoxCipher();
    var nonce = XChaChaNonce.Generate();
    var message = Encoding.UTF8.GetBytes("Test Message");
    var ciphertext = secretBoxCipher.Encrypt(message, key, nonce);
}

Decryption

var keyBytes = Convert.FromBase64String("XPRT6QuYZDdytKM55WW+gnZklhaJBcDnOWi1kEI2we4=");
var nonceBytes = Convert.FromBase64String("2eQuiE8Fy70rwlCAi5T2oVEj5MrwxJaT");
var ciphertext = Convert.FromBase64String("w2jUPkWL0PfvnNFM7xq4o9gcVKrMTkd6SsYhLQ==");
using (var key = new XChaChaKey(keyBytes))
{
    var secretBoxCipher = new XChaChaSecretBoxCipher();
    var nonce = new XChaChaNonce(nonceBytes);
    var message = secretBoxCipher.Decrypt(ciphertext, key, nonce);
}

Additional APIs

TryDecrypt

Decrypt will throw a CryptographicException if the decryption fails. Instead, TryDecrypt will return true or false depending on whether the decryption succeeded:

    ...
    bool success = secretBoxCipher.TryDecrypt(ciphertext, message, key, nonce);

Using a buffer

Overloads of Encrypt/Decrypt/TryDecrypt allow passing in a buffer for the ciphertext/plaintext as demonstrated in the following examples:

Encryption

using (var key = XChaChaKey.Generate())
{
    var secretBoxCipher = new XChaChaSecretBoxCipher();
    var nonce = XChaChaNonce.Generate();
    var message = Encoding.UTF8.GetBytes("Test Message");
    var ciphertext = new byte[secretBoxCipher.GetCipherTextLength(message.Length)];
    secretBoxCipher.Encrypt(message, ciphertext, key, nonce);
}

Decryption

var keyBytes = Convert.FromBase64String("XPRT6QuYZDdytKM55WW+gnZklhaJBcDnOWi1kEI2we4=");
var nonceBytes = Convert.FromBase64String("2eQuiE8Fy70rwlCAi5T2oVEj5MrwxJaT");
var ciphertext = Convert.FromBase64String("w2jUPkWL0PfvnNFM7xq4o9gcVKrMTkd6SsYhLQ==");
using (var key = new XChaChaKey(keyBytes))
{
    var secretBoxCipher = new XChaChaSecretBoxCipher();
    var nonce = new XChaChaNonce(nonceBytes);
    var message = new byte[secretBoxCipher.GetPlaintextLength(ciphertext.Length)];
    secretBoxCipher.Decrypt(ciphertext, message, key, nonce);
}