Implement streaming non-AES encryption and decryption

This commit is contained in:
Daniel Huigens 2020-01-31 22:48:53 +01:00
parent 2ec8831abf
commit fc0052e35a
2 changed files with 37 additions and 33 deletions

View File

@ -60,23 +60,26 @@ export default {
const cipherfn = new cipher[algo](key); const cipherfn = new cipher[algo](key);
const block_size = cipherfn.blockSize; const block_size = cipherfn.blockSize;
let blocki = new Uint8Array(block_size);
const blockc = iv.slice(); const blockc = iv.slice();
let pos = 0; let pt = new Uint8Array();
const ciphertext = new Uint8Array(plaintext.length); const process = chunk => {
let i; if (chunk) {
let j = 0; pt = util.concatUint8Array([pt, chunk]);
while (plaintext.length > block_size * pos) {
const encblock = cipherfn.encrypt(blockc);
blocki = plaintext.subarray((pos * block_size), (pos * block_size) + block_size);
for (i = 0; i < blocki.length; i++) {
blockc[i] = blocki[i] ^ encblock[i];
ciphertext[j++] = blockc[i];
} }
pos++; const ciphertext = new Uint8Array(pt.length);
} let i;
return ciphertext; let j = 0;
while (chunk ? pt.length >= block_size : pt.length) {
const encblock = cipherfn.encrypt(blockc);
for (i = 0; i < block_size; i++) {
blockc[i] = pt[i] ^ encblock[i];
ciphertext[j++] = blockc[i];
}
pt = pt.subarray(block_size);
}
return ciphertext.subarray(0, j);
};
return stream.transform(plaintext, process, process);
}, },
decrypt: async function(algo, key, ciphertext, iv) { decrypt: async function(algo, key, ciphertext, iv) {
@ -87,28 +90,29 @@ export default {
return aesDecrypt(algo, key, ciphertext, iv); return aesDecrypt(algo, key, ciphertext, iv);
} }
ciphertext = await stream.readToEnd(ciphertext);
const cipherfn = new cipher[algo](key); const cipherfn = new cipher[algo](key);
const block_size = cipherfn.blockSize; const block_size = cipherfn.blockSize;
let blockp = iv; let blockp = iv;
let pos = 0; let ct = new Uint8Array();
const plaintext = new Uint8Array(ciphertext.length); const process = chunk => {
const offset = 0; if (chunk) {
let i; ct = util.concatUint8Array([ct, chunk]);
let j = 0;
while (ciphertext.length > (block_size * pos)) {
const decblock = cipherfn.encrypt(blockp);
blockp = ciphertext.subarray((pos * (block_size)) + offset, (pos * (block_size)) + (block_size) + offset);
for (i = 0; i < blockp.length; i++) {
plaintext[j++] = blockp[i] ^ decblock[i];
} }
pos++; const plaintext = new Uint8Array(ct.length);
} let i;
let j = 0;
return plaintext; while (chunk ? ct.length >= block_size : ct.length) {
const decblock = cipherfn.encrypt(blockp);
blockp = ct;
for (i = 0; i < block_size; i++) {
plaintext[j++] = blockp[i] ^ decblock[i];
}
ct = ct.subarray(block_size);
}
return plaintext.subarray(0, j);
};
return stream.transform(ciphertext, process, process);
} }
}; };

View File

@ -300,7 +300,7 @@ SecretKey.prototype.encrypt = async function (passphrase) {
this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array()); this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array());
} else { } else {
this.s2k_usage = 254; this.s2k_usage = 254;
this.keyMaterial = crypto.cfb.encrypt(this.symmetric, key, util.concatUint8Array([ this.keyMaterial = await crypto.cfb.encrypt(this.symmetric, key, util.concatUint8Array([
cleartext, cleartext,
await crypto.hash.sha1(cleartext) await crypto.hash.sha1(cleartext)
]), this.iv); ]), this.iv);