A straightforward form of encryption using a passphrase (or a shared secret) that can be useful in web-based environments - especially in storage and transport. Consider e.g. securing sensitive user data in localStorage
, or sending data via a third-party server (such as a serverless endpoint).
This method uses a passphrase to encrypt and decrypt any string
, number
, array
, or other JSON-compatible object
using AES in GCM mode and is ideal for cases where one party is both encrypting and decrypting. For cases where you are sending encrypted data to other parties you might consider alternative methods, such as public-key cryptography. For a comprehensive rundown of encryption methods available in the browser, refer to MDN's SubtleCrypto documentation.
// store the script locally and import
import { encryptData, decryptData } from './passphrase-encryption.js'
// a passphrase to be used for encryption and decryption
const passphrase = 'its a secret';
// a simple json-compatible object to encrypt
const dataToEncrypt = { a: 'list', of: [1, 2, 3, 4, 5, 'example'], items: { to: 'encrypt' } };
// encrypt the data ...
// encryption returns a base64 encoded cyphertext (the encrypted data) and an IV (initialisation vector)
// these can be safely stored/transported together, in public
const { iv, data } = await encryptData(dataToEncrypt, passphrase);
console.log({ iv, data })
// you could then create a string for transport
const estring = `${iv}|${data}`;
// and then retrieve the components with a selective split
const [ivFromString, dataFromString] = estring.split(/\|(.*)/, 2);
// or store the encrypted data in localStorage
localStorage.setItem('this-is-encrypted', JSON.stringify({ iv, data }));
// and wait for a month before retrieving it
const { iv: ivFromStorage, data: dataFromStorage } = JSON.parse(localStorage.getItem('this-is-encrypted'));
// and then decrypt it, ensuring you pass in the encrypted data and IV as per the original encryption
const decrypted = await decryptData({ iv: ivFromStorage, data: dataFromStorage }, passphrase);
// your decrypted data should be idenitical (but not equal) to your original object
console.log({ decrypted })
Comments, suggestions & improvements welcome! 🤙