Skip to content

Examples

XeroXP edited this page Jun 9, 2022 · 2 revisions

secretbox

An example using symmetrical crypto, a single key for encrypting and decrypting.

using Newtonsoft.Json;
using TweetNaclSharp;
using TweetNaclSharp.Util;

var newNonce = () => Nacl.RandomBytes(Nacl.SecretboxNonceLength);

var generateKey = () => NaclUtil.EncodeBase64(Nacl.RandomBytes(Nacl.SecretboxKeyLength));

var encrypt = (object json, string key) => {
	var keyUint8Array = NaclUtil.DecodeBase64(key);

	var nonce = newNonce();
	var messageUint8 = NaclUtil.DecodeUTF8(JsonConvert.SerializeObject(json));
	var box = Nacl.Secretbox(messageUint8, nonce, keyUint8Array);

	var fullMessage = new byte[nonce.Length + box.Length];
	Buffer.BlockCopy(nonce, 0, fullMessage, 0, nonce.Length);
	Buffer.BlockCopy(box, 0, fullMessage, nonce.Length, box.Length);

	var base64FullMessage = NaclUtil.EncodeBase64(fullMessage);
	return base64FullMessage;
};

var decrypt = (string messageWithNonce, string key) => {
	var keyUint8Array = NaclUtil.DecodeBase64(key);
	var messageWithNonceAsUint8Array = NaclUtil.DecodeBase64(messageWithNonce);
	var nonce = new byte[Nacl.SecretboxNonceLength];
	Buffer.BlockCopy(messageWithNonceAsUint8Array, 0, nonce, 0, Nacl.SecretboxNonceLength);
	var message = new byte[messageWithNonceAsUint8Array.Length - Nacl.SecretboxNonceLength];
	Buffer.BlockCopy(messageWithNonceAsUint8Array, Nacl.SecretboxNonceLength, message, 0, messageWithNonceAsUint8Array.Length - Nacl.SecretboxNonceLength);

	var decrypted = Nacl.SecretboxOpen(message, nonce, keyUint8Array);

	if (decrypted == null)
	{
		throw new Exception("Could not decrypt message");
	}

	var base64DecryptedMessage = NaclUtil.EncodeUTF8(decrypted);
	return JsonConvert.DeserializeObject<object>(base64DecryptedMessage);
};

var key = generateKey();
var obj = new { hello = "world" };
var encrypted = encrypt(obj, key);
var decrypted = decrypt(encrypted, key);
Console.WriteLine(JsonConvert.SerializeObject(decrypted) + '\n' +  JsonConvert.SerializeObject(obj)); // should be shallow equal

box

Example using asymmetric public key encryption. A secret and public key pair are generated twice (pairA, pairB) and data is encrypted with pairA.secretKey+pairB.publicKey and decrypted with pairB.secretKey+pairA.publicKey.

using Newtonsoft.Json;
using TweetNaclSharp;
using TweetNaclSharp.Util;

var newNonce = () => Nacl.RandomBytes(Nacl.BoxNonceLength);
var generateKeyPair = () => Nacl.BoxKeyPair();

var encrypt = (byte[] secretOrSharedKey, object json, byte[] key) => {
	var nonce = newNonce();
	var messageUint8 = NaclUtil.DecodeUTF8(JsonConvert.SerializeObject(json));
	var encrypted = key != null
	  ? Nacl.Box(messageUint8, nonce, key, secretOrSharedKey)
	  : Nacl.BoxAfter(messageUint8, nonce, secretOrSharedKey);

	var fullMessage = new byte[nonce.Length + encrypted.Length];
	Buffer.BlockCopy(nonce, 0, fullMessage, 0, nonce.Length);
	Buffer.BlockCopy(encrypted, 0, fullMessage, nonce.Length, encrypted.Length);

	var base64FullMessage = NaclUtil.EncodeBase64(fullMessage);
	return base64FullMessage;
};

var decrypt = (byte[] secretOrSharedKey, string messageWithNonce, byte[] key) => {
	var messageWithNonceAsUint8Array = NaclUtil.DecodeBase64(messageWithNonce);
	var nonce = new byte[Nacl.BoxNonceLength];
	Buffer.BlockCopy(messageWithNonceAsUint8Array, 0, nonce, 0, Nacl.BoxNonceLength);
	var message = new byte[messageWithNonceAsUint8Array.Length - Nacl.BoxNonceLength];
	Buffer.BlockCopy(messageWithNonceAsUint8Array, Nacl.BoxNonceLength, message, 0, messageWithNonceAsUint8Array.Length - Nacl.BoxNonceLength);

	var decrypted = key != null
	  ? Nacl.BoxOpen(message, nonce, key, secretOrSharedKey)
	  : Nacl.BoxOpenAfter(message, nonce, secretOrSharedKey);

	if (decrypted == null)
	{
		throw new Exception("Could not decrypt message");
	}

	var base64DecryptedMessage = NaclUtil.EncodeUTF8(decrypted);
	return JsonConvert.DeserializeObject<object>(base64DecryptedMessage);
};

var obj = new { hello = "world" };
var pairA = generateKeyPair();
var pairB = generateKeyPair();
var sharedA = Nacl.BoxBefore(pairB.PublicKey, pairA.SecretKey);
var sharedB = Nacl.BoxBefore(pairA.PublicKey, pairB.SecretKey);
var encrypted = encrypt(sharedA, obj, null);
var decrypted = decrypt(sharedB, encrypted, null);
Console.WriteLine(JsonConvert.SerializeObject(obj) + '\n' + JsonConvert.SerializeObject(encrypted) + '\n' + JsonConvert.SerializeObject(decrypted));
Clone this wiki locally