From 379431eefd9a0c702d5f9a2459759a97cb742cd0 Mon Sep 17 00:00:00 2001 From: azivner Date: Thu, 16 Nov 2017 00:22:00 -0500 Subject: [PATCH] fixed encryption of note history --- migrations/0031__change_encryption_to_CBC.js | 4 --- routes/api/note_history.js | 2 +- services/data_encryption.js | 33 ++++++-------------- services/notes.js | 29 +++++++---------- services/password_encryption.js | 2 -- 5 files changed, 22 insertions(+), 48 deletions(-) diff --git a/migrations/0031__change_encryption_to_CBC.js b/migrations/0031__change_encryption_to_CBC.js index 5765a1051..65696bfa4 100644 --- a/migrations/0031__change_encryption_to_CBC.js +++ b/migrations/0031__change_encryption_to_CBC.js @@ -20,12 +20,8 @@ module.exports = async () => { const protectedNotes = await sql.getResults("SELECT * FROM notes WHERE is_protected = 1"); for (const note of protectedNotes) { - console.log("Encrypted: ", note.note_title); - const decryptedTitle = data_encryption.decrypt(dataKey, note.note_title); - console.log("Decrypted title: ", decryptedTitle); - note.note_title = data_encryption.encryptCbc(dataKey, "0" + note.note_id, decryptedTitle); const decryptedText = data_encryption.decrypt(dataKey, note.note_text); diff --git a/routes/api/note_history.js b/routes/api/note_history.js index ecc875c45..0dff4005e 100644 --- a/routes/api/note_history.js +++ b/routes/api/note_history.js @@ -16,7 +16,7 @@ router.get('/:noteId', auth.checkApiAuth, async (req, res, next) => { for (const hist of history) { if (hist.is_protected) { hist.note_title = data_encryption.decryptCbcString(dataKey, data_encryption.noteTitleIv(hist.note_history_id), hist.note_title); - hist.note_text = data_encryption.decryptCbcString(dataKey, data_encryption.noteTitleIv(hist.note_history_id), hist.note_text); + hist.note_text = data_encryption.decryptCbcString(dataKey, data_encryption.noteTextIv(hist.note_history_id), hist.note_text); } } diff --git a/services/data_encryption.js b/services/data_encryption.js index 375d4579b..82f0b86dd 100644 --- a/services/data_encryption.js +++ b/services/data_encryption.js @@ -4,10 +4,6 @@ const utils = require('./utils'); const aesjs = require('./aes'); const crypto = require('crypto'); -function getProtectedSessionId(req) { - return req.headers['x-protected-session-id']; -} - function getDataAes(dataKey) { return new aesjs.ModeOfOperation.ctr(dataKey, new aesjs.Counter(5)); } @@ -73,12 +69,8 @@ function sha256Array(content) { } function pad(data) { - console.log("Before padding: ", data); - let padded = Array.from(data); - console.log("After arraying: ", padded); - if (data.length >= 16) { padded = padded.slice(0, 16); } @@ -86,19 +78,17 @@ function pad(data) { padded = padded.concat(Array(16 - padded.length).fill(0)); } - console.log("Before buffering: ", padded); - return Buffer.from(padded); } -function encryptCbc(dataKey, iv, plainText) { - if (!dataKey) { +function encryptCbc(key, iv, plainText) { + if (!key) { throw new Error("No data key!"); } const plainTextBuffer = Buffer.from(plainText); - const cipher = crypto.createCipheriv('aes-128-cbc', pad(dataKey), pad(iv)); + const cipher = crypto.createCipheriv('aes-128-cbc', pad(key), pad(iv)); const digest = shaArray(plainTextBuffer).slice(0, 4); @@ -109,29 +99,25 @@ function encryptCbc(dataKey, iv, plainText) { return encryptedData.toString('base64'); } -function decryptCbc(dataKey, iv, cipherText) { - if (!dataKey) { +function decryptCbc(key, iv, cipherText) { + if (!key) { return "[protected]"; } - console.log("Key: ", pad(dataKey)); + console.log("key:", key); + console.log("iv:", iv); + console.log("cipherText:", cipherText); - const decipher = crypto.createDecipheriv('aes-128-cbc', pad(dataKey), pad(iv)); + const decipher = crypto.createDecipheriv('aes-128-cbc', pad(key), pad(iv)); const cipherTextBuffer = Buffer.from(cipherText, 'base64'); const decryptedBytes = Buffer.concat([decipher.update(cipherTextBuffer), decipher.final()]); - console.log("decrypted: ", decryptedBytes); - const digest = decryptedBytes.slice(0, 4); const payload = decryptedBytes.slice(4); - console.log("payload: ", payload); - const computedDigest = shaArray(payload).slice(0, 4); - console.log("Hash arr: ", computedDigest); - if (!arraysIdentical(digest, computedDigest)) { return false; } @@ -154,7 +140,6 @@ function noteTextIv(iv) { } module.exports = { - getProtectedSessionId, decrypt, encrypt, encryptCbc, diff --git a/services/notes.js b/services/notes.js index 105666604..04627b60a 100644 --- a/services/notes.js +++ b/services/notes.js @@ -134,6 +134,9 @@ async function protectNoteHistory(noteId, dataKey, protect) { } async function updateNote(noteId, newNote, ctx) { + let noteTitleForHistory = newNote.detail.note_title; + let noteTextForHistory = newNote.detail.note_text; + if (newNote.detail.is_protected) { await encryptNote(newNote, ctx); } @@ -146,36 +149,28 @@ async function updateNote(noteId, newNote, ctx) { const historyCutoff = now - historySnapshotTimeInterval; - let noteHistoryId = await sql.getSingleValue("select note_history_id from notes_history where note_id = ? and date_modified_from >= ?", [noteId, historyCutoff]); + const existingNoteHistoryId = await sql.getSingleValue("select note_history_id from notes_history where note_id = ? and date_modified_from >= ?", [noteId, historyCutoff]); await sql.doInTransaction(async () => { - if (noteHistoryId) { - await sql.execute("update notes_history set note_title = ?, note_text = ?, is_protected = ?, date_modified_to = ? where note_history_id = ?", [ - newNote.detail.note_title, - newNote.detail.note_text, - newNote.detail.is_protected, - now, - noteHistoryId - ]); - } - else { - noteHistoryId = utils.randomString(16); + if (!existingNoteHistoryId) { + const newNoteHistoryId = utils.randomString(16); await sql.execute("insert into notes_history (note_history_id, note_id, note_title, note_text, is_protected, date_modified_from, date_modified_to) " + "values (?, ?, ?, ?, ?, ?, ?)", [ - noteHistoryId, + newNoteHistoryId, noteId, - newNote.detail.note_title, - newNote.detail.note_text, - newNote.detail.is_protected, + noteTitleForHistory, + noteTextForHistory, + false, // we don't care about encryption - this will be handled in protectNoteHistory() now, now ]); + + await sql.addNoteHistorySync(newNoteHistoryId); } await protectNoteHistory(noteId, ctx.getDataKey(), newNote.detail.is_protected); - await sql.addNoteHistorySync(noteHistoryId); await addNoteAudits(origNoteDetail, newNote.detail, ctx.browserId); await sql.execute("update notes set note_title = ?, note_text = ?, is_protected = ?, date_modified = ? where note_id = ?", [ diff --git a/services/password_encryption.js b/services/password_encryption.js index bb2ed634a..2d59e84e5 100644 --- a/services/password_encryption.js +++ b/services/password_encryption.js @@ -70,8 +70,6 @@ async function getDecryptedDataKeyCbc(password) { const decryptedDataKey = data_encryption.decryptCbc(passwordDerivedKey, encryptedDataKeyIv, encryptedDataKey); - console.log("Decrypted data key: ", decryptedDataKey); - return decryptedDataKey; }