diff --git a/cli_create.sh b/cli_create.sh index 69f9bce..736e471 100644 --- a/cli_create.sh +++ b/cli_create.sh @@ -22,7 +22,7 @@ SECRET=${1:-} pass=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 20 || true) # Encrypt the secret -ciphertext=$(echo "${SECRET}" | openssl aes-256-cbc -base64 -pass "pass:${pass}" -iter 300000 -md sha512 2>/dev/null) +ciphertext=$(echo "${SECRET}" | openssl aes-256-cbc -base64 -A -pass "pass:${pass}" -iter 300000 -md sha512 2>/dev/null) # Create a secret and extract the secret ID id=$( diff --git a/cli_get.sh b/cli_get.sh index 03ce712..96208fc 100644 --- a/cli_get.sh +++ b/cli_get.sh @@ -25,4 +25,4 @@ geturl="${host}/api/get/${id}" # fetch secret and decrypt to STDOUT curl -sSf "${geturl}" | jq -r ".secret" | - openssl aes-256-cbc -base64 -pass "pass:${pass}" -iter 300000 -md sha512 -d 2>/dev/null + openssl aes-256-cbc -base64 -A -pass "pass:${pass}" -iter 300000 -md sha512 -d diff --git a/package-lock.json b/package-lock.json index 60fb383..79c3138 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "name": "ots", "dependencies": { + "base64-js": "^1.5.1", "bootstrap": "^5.3.2", "qrcode": "^1.5.3", "vue": "^2.7.14", @@ -1166,7 +1167,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", diff --git a/package.json b/package.json index 32385da..da55311 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "name": "ots", "private": true, "dependencies": { + "base64-js": "^1.5.1", "bootstrap": "^5.3.2", "qrcode": "^1.5.3", "vue": "^2.7.14", diff --git a/src/crypto.js b/src/crypto.js index a6c289f..32be908 100644 --- a/src/crypto.js +++ b/src/crypto.js @@ -1,29 +1,8 @@ +import base64 from 'base64-js' + const opensslBanner = new Uint8Array(new TextEncoder('utf8').encode('Salted__')) const pbkdf2Params = { hash: 'SHA-512', iterations: 300000, name: 'PBKDF2' } -/** - * @param {ArrayBuffer} data Data to encode to base64 - * @returns String - */ -function abToB64(data) { - const outdata = [] - const bytes = new Uint8Array(data) - for (let i = 0; i < bytes.byteLength; i++) { - outdata.push(String.fromCodePoint(bytes[i])) - } - return btoa(outdata.join('')) -} - -/** - * - * @param {String} encoded Base64 encoded data - * @returns ArrayBuffer - */ -function b64ToAb(encoded) { - const binary = atob(encoded) - return Uint8Array.from(binary, c => c.codePointAt(0)).buffer -} - /** * @param {String} cipherText Encrypted data in base64 encoded form * @param {String} passphrase Encryption passphrase used for key-derivation @@ -48,7 +27,7 @@ function enc(plainText, passphrase) { * @returns String */ function decrypt(passphrase, encData) { - const data = new Uint8Array(b64ToAb(encData)) + const data = base64.toByteArray(encData) return deriveKey(passphrase, data.slice(8, 16)) .then(({ iv, key }) => window.crypto.subtle.decrypt({ iv, name: 'AES-CBC' }, key, data.slice(16))) @@ -78,7 +57,7 @@ function encrypt(passphrase, salt, plainData) { return deriveKey(passphrase, salt) .then(({ iv, key }) => window.crypto.subtle.encrypt({ iv, name: 'AES-CBC' }, key, new TextEncoder('utf8').encode(plainData))) .then(encData => new Uint8Array([...opensslBanner, ...salt, ...new Uint8Array(encData)])) - .then(data => abToB64(data.buffer)) + .then(data => base64.fromByteArray(data)) } /** @@ -91,4 +70,4 @@ function generateSalt() { return window.crypto.getRandomValues(salt) } -export default { abToB64, b64ToAb, dec, enc } +export default { dec, enc } diff --git a/src/ots-meta.js b/src/ots-meta.js index a7b90e2..fb4be99 100644 --- a/src/ots-meta.js +++ b/src/ots-meta.js @@ -1,4 +1,4 @@ -import appCrypto from './crypto' +import base64 from 'base64-js' /** * OTSMeta defines the structure of (de-)serializing stored payload for secrets @@ -33,7 +33,7 @@ class OTSMeta { this.#version = data.v for (const f of data.attachments || []) { - const content = appCrypto.b64ToAb(f.data) + const content = base64.toByteArray(f.data) this.#files.push(new File([content], f.name, { type: f.type })) } } @@ -75,7 +75,7 @@ class OTSMeta { for (const f of this.#files) { encodes.push(f.arrayBuffer() .then(ab => { - const data = appCrypto.abToB64(ab) + const data = base64.fromByteArray(new Uint8Array(ab)) output.attachments.push({ data, name: f.name, type: f.type }) })) }