4.4 KiB
Encrypted Streams
See also: Libsodium's documentation on its encrypted streams feature
crypto_secretstream_xchacha20poly1305_init_push()
Initialize a stream for streaming encryption.
Parameters and their respective types:
{CryptographyKey}key
Returns a Promise that resolves to an array with 2 elements:
- A 24-byte header that should be included in the encrypted stream.
- A backend-specific
state:LibsodiumWrappersreturns anumber(a pointer to an internal buffer)SodiumNativereturns aCryptoSecretstreamXchacha20poly1305StateWrapobject
The {state} type annotation below refers to one of the backend-specific state
types.
You'll typically want to use it with list unpacking syntax, like so:
[state, header] = await sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
crypto_secretstream_xchacha20poly1305_init_pull()
Initialize a stream for streaming decryption.
Parameters and their respective types:
{CryptographyKey}key{Buffer}header (must be 24 bytes)
Returns a Promise that resolves to a backend-specific state:
LibsodiumWrappersreturns anumber(a pointer to an internal buffer)SodiumNativereturns aCryptoSecretstreamXchacha20poly1305StateWrapobject
The {state} type annotation below refers to one of the backend-specific state
types.
crypto_secretstream_xchacha20poly1305_push()
Encrypt some data in a stream.
Parameters and their respective types:
{state}state{string|Buffer}message{string|Buffer}(optional) additional associated data{number}tag (default = 0, see libsodium docs)
Returns a Promise that resolves to a Buffer containing the ciphertext.
crypto_secretstream_xchacha20poly1305_pull()
Decrypt some data in a stream.
Parameters and their respective types:
{state}state{string|Buffer}ciphertext{string|Buffer}(optional) additional associated data{number}tag (default = 0, see libsodium docs)
Returns a Promise that resolves to a Buffer containing
decrypted plaintext.
crypto_secretstream_xchacha20poly1305_keygen()
Returns a CryptographyKey object containing a key appropriate
for the crypto_secretstream API.
crypto_secretstream_xchacha20poly1305_rekey()
Deterministic re-keying of the internal state.
Parameters and their respective types:
{state}state
Returns a Promise that resolves to undefined. Instead,
the state variable is overwritten in-place.
Example for crypto_secretstream_xchacha20poly1305
const fsp = require('fs').promises;
const path = require('path');
const { SodiumPlus } = require('sodium-plus');
let sodium;
(async function () {
if (!sodium) sodium = await SodiumPlus.auto();
let key = await sodium.crypto_secretstream_xchacha20poly1305_keygen();
let pushState, pullState, header;
[pushState, header] = await sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
// Get a test input from the text file.
let longText = await fsp.readFile(path.join(__dirname, 'encrypted-streams.md'));
let chunk, readUntil;
let ciphertext = Buffer.concat([header]);
// How big are our chunks going to be?
let PUSH_CHUNK_SIZE = await sodium.randombytes_uniform(longText.length - 32) + 32;
let PULL_CHUNK_SIZE = PUSH_CHUNK_SIZE + sodium.CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES;
// Encryption...
for (let i = 0; i < longText.length; i += PUSH_CHUNK_SIZE) {
readUntil = (i + PUSH_CHUNK_SIZE) > longText.length ? longText.length : i + PUSH_CHUNK_SIZE;
chunk = await sodium.crypto_secretstream_xchacha20poly1305_push(
pushState,
longText.slice(i, readUntil)
);
ciphertext = Buffer.concat([ciphertext, chunk]);
}
pullState = await sodium.crypto_secretstream_xchacha20poly1305_init_pull(key, header);
// Decrypt, starting at 24 (after the header, which we already have)
let decrypted = Buffer.alloc(0);
for (let i = 24; i < ciphertext.length; i += PULL_CHUNK_SIZE) {
readUntil = (i + PULL_CHUNK_SIZE) > ciphertext.length ? ciphertext.length : i + PULL_CHUNK_SIZE;
chunk = await sodium.crypto_secretstream_xchacha20poly1305_pull(
pullState,
ciphertext.slice(i, readUntil)
);
decrypted = Buffer.concat([decrypted, chunk]);
}
console.log(decrypted.toString());
})();