Skip to content

Instantly share code, notes, and snippets.

@ambar
Last active February 7, 2018 11:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ambar/7fe6c71e76e8be583bb64b78529100b4 to your computer and use it in GitHub Desktop.
Save ambar/7fe6c71e76e8be583bb64b78529100b4 to your computer and use it in GitHub Desktop.
web crypto for AES-CBC
const atos = a =>
Array.from(a)
.map(c => String.fromCodePoint(c))
.join('')
const stoa = s => Array.from(s).map(c => c.codePointAt())
const createAes = (keyString, ivString) => {
const keyUtf8 = new TextEncoder().encode(keyString)
const ivUtf8 = new TextEncoder().encode(ivString)
const alg = {name: 'AES-CBC', iv: ivUtf8}
let key
const getKey = () => {
if (!key) {
key = crypto.subtle.importKey('raw', keyUtf8, alg, false, [
'encrypt',
'decrypt',
])
}
return key
}
const encrypt = async (input, to = 'arraybuffer') => {
const data = ArrayBuffer.isView(input)
? input
: new TextEncoder().encode(input)
const ab = await crypto.subtle.encrypt(alg, await getKey(), data)
if (to === 'string') {
return atos(new Uint8Array(ab))
} else if (to === 'base64') {
return btoa(atos(new Uint8Array(ab)))
}
return ab
}
const decrypt = async (encrypted, to = 'arraybuffer') => {
const ab = await crypto.subtle.decrypt(alg, await getKey(), encrypted)
if (to === 'string') {
return new TextDecoder().decode(ab)
}
return ab
}
const decryptBase64 = (b64String, to) => {
return decrypt(new Uint8Array(stoa(atob(b64String))), to)
}
const decryptString = (string, to) => {
return decrypt(new Uint8Array(stoa(string)), to)
}
return {encrypt, decrypt, decryptBase64, decryptString}
}
exports.createAes = createAes
const mainB64 = async () => {
const aes = createAes(KEY, IV)
const ctB64 = await aes.encrypt(message, 'base64')
console.info('encrypted:b64', ctB64)
const pt = await aes.decryptBase64(ctB64, 'string')
console.assert(pt === message)
}
const main = async () => {
const aes = createAes(KEY, IV)
const ct = await aes.encrypt(message, 'string')
console.info('encrypted:string', ct)
const pt = await aes.decryptString(ct, 'string')
console.info('decrypted:string', pt)
console.assert(pt === message)
}
mainAb()
mainB64()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment