ravenous.dev/resources/protect.js

// prevent information, such as email addresses, from being scraped by bots

const password = "no bots allowed!";
var key, iv;

async function encrypt(text) {
	let encoded = new TextEncoder().encode(text);
	const ciphertext = await crypto.subtle.encrypt(
		{ name: "AES-GCM", iv },
		key,
		encoded
	);
	return new Uint8Array(ciphertext).toBase64();
}

async function decrypt(encrypted) {
	const ciphertext = Uint8Array.fromBase64(encrypted).buffer;
	const decrypted = await crypto.subtle.decrypt(
		{ name: "AES-GCM", iv },
		key,
		ciphertext
	);
	return new TextDecoder().decode(decrypted);
}

(async () => {
	const hash = await crypto.subtle.digest(
		"SHA-256", new TextEncoder().encode(password)
	);
	key = await crypto.subtle.importKey(
		"raw",
		hash,
		"AES-GCM",
		false,
		["encrypt", "decrypt"]
	);
	iv = hash.slice(0, 12);

	document.querySelectorAll(".protected").forEach(async (prot) => {
		console.log(prot.attributes);
		for (let i in prot.attributes) {
			const attr = prot.attributes[i];
			console.log(attr);
			if (attr.nodeName == "text") {
				let val = await decrypt(prot.getAttribute(attr.nodeName));
				prot.innerText = val;
			} else if (attr.nodeName.startsWith("prot-")) {
				let val = await decrypt(prot.getAttribute(attr.nodeName));
				prot.setAttribute(attr.nodeName.substring("prot-".length), val);
			}
		}
	});
})().then().catch(err => console.error(err));