UNPKG

@meeco/cryppo

Version:

In-browser encryption and decryption. Clone of Ruby Cryppo

74 lines 2.97 kB
import forge from 'node-forge'; import { EncryptionKey } from '../encryption-key.js'; import { generateDerivedKey } from '../key-derivation/pbkdf2-hmac.js'; import { SerializationFormat } from '../serialization-versions.js'; import { binaryStringToBytesBuffer, serialize } from '../util.js'; const { cipher: forgeCipher, random, util } = forge; export async function encryptWithGeneratedKey({ data, strategy, keyLength, iv }, serializationVersion = SerializationFormat.latest_version) { const key = EncryptionKey.generateRandom(keyLength || 32); const result = await encryptWithKey({ key, data, strategy, iv }, serializationVersion); return { ...result, generatedKey: key, }; } export async function encryptWithKeyDerivedFromString({ passphrase, data, strategy, iv, serializationVersion = SerializationFormat.latest_version, }) { const derived = await generateDerivedKey({ passphrase }); const result = await encryptWithKey({ key: derived.key, data, strategy, iv, }, serializationVersion); const serializedKey = derived.options.serialize(serializationVersion); result.serialized = `${result.serialized}.${serializedKey}`; return { ...result, ...derived, }; } export async function encryptWithKey({ key, data, strategy, iv }, serializationVersion = SerializationFormat.latest_version) { if (!data || data.length === 0) { return { encrypted: null, serialized: null, }; } const output = encryptWithKeyUsingArtefacts({ key, data, strategy, iv }); const { encrypted, artifacts } = output; const keyLengthBits = key.bytes.length * 8; const [cipher, mode] = strategy.split('-').map(upperWords); const serialized = serialize(`${cipher}${keyLengthBits}${mode}`, encrypted || '', artifacts, serializationVersion); return { encrypted, serialized, }; } /** * UpperCamelCase helper */ const upperWords = (val) => val.slice(0, 1).toUpperCase() + val.slice(1).toLowerCase(); export function encryptWithKeyUsingArtefacts({ key, data, strategy, iv }) { if (data.length === 0) { return { encrypted: null }; } // @ts-expect-error node-forge createBuffer accepts Uint8Array at runtime const cipher = forgeCipher.createCipher(strategy, util.createBuffer(key.bytes)); iv = iv || random.getBytesSync(12); cipher.start({ iv: util.createBuffer(iv), additionalData: 'none', tagLength: 128 }); // @ts-expect-error node-forge createBuffer accepts Uint8Array at runtime cipher.update(util.createBuffer(data)); cipher.finish(); const artifacts = { iv: binaryStringToBytesBuffer(iv), }; if (cipher.mode.tag) { artifacts.at = binaryStringToBytesBuffer(cipher.mode.tag.data); } artifacts.ad = 'none'; return { encrypted: cipher.output.data, artifacts, }; } //# sourceMappingURL=encryption.js.map