Does a rolling block encryption algorithm exist?
I am making a note taking web app which saves notes continuously as you type. I am sending diffs t开发者_如何学JAVAo prevent sending too much data over the wire, which works fine when the note is plain text.
However, I am adding support for encrypted notes, so notes only ever leave the browser in encrypted form (so that notes can contain sensitive information with no chance of anybody who doesn't know the passphrase (which also never leaves the browser) reading them, not even one with full access to the database). However, all changes to notes currently completely change the encrypted text, so I have to send the entire note back to the server every second or two while it's being edited.
Based on the my reading recently, I could (but shouldn't) use an ECB block cipher encryption mode, which breaks the plaintext into 16 byte chunks and encrypts them independently. This would mean diffing would work if the edits were happening at the end (or if the edit added or removed a multiple of 16 bytes). But any edits that happen in the middle of a note will affect the encrypted text for the rest of the note.
So, as I lay in bed last night, I started wondering if there existed a "rolling block" encryption algorithm that encrypted each part of the note based on the characters around it, so that changing/adding/deleting any one character would only change the 16 surrounding bytes. Hopefully that makes sense. Basically, I want an encryption algorithm so that small changes to the plaintext make fairly small changes to the encrypted text.
Does such an algorithm exist? (Would it be another block cipher mode of operation that could be used with AES, rather than a complete new algorithm? And how would its security compare with a more normal block cipher mode?)
I originally had this as a JavaScript question, because that's what I ultimately want, but that's probably asking a bit much.
You'll want to use a stream cipher mode of operation like CFB, OFB or CTR instead of a block cipher mode like ECB or CBC. See block ciphers modes of operation. You can use these with common encryption algorithms like AES and Blowfish. Stream cipher modes like CTR are often used for programs like SSH since you're entering one character at a time.
You can still use CBC - it's just that whenever a sequence of blocks in the middle of the message is updated, you'll have to remember the old value of the ciphertext of the last block in that sequence. For example, the given the original text:
| IV 0 |
| Plaintext 0 | <=====> | Ciphertext 0 |
| Plaintext 1 | <=====> | Ciphertext 1 |
| Plaintext 2 | <=====> | Ciphertext 2 |
| Plaintext 3 | <=====> | Ciphertext 3 |
| Plaintext 4 | <=====> | Ciphertext 4 |
| Plaintext 5 | <=====> | Ciphertext 5 |
If the client wants to update blocks 2 and 3, it uses Ciphertext 1
as the IV for CBC, and sends the new ciphertext blocks Ciphertext 2b
and Ciphertext 3b
. The server then retains Ciphertext 3
as IV 1
, so it now looks like:
| IV 0 |
| Plaintext 0 | <=====> | Ciphertext 0 |
| Plaintext 1 | <=====> | Ciphertext 1 |
| Plaintext 2 | <=====> | Ciphertext 2b |
| Plaintext 3 | <=====> | Ciphertext 3b |
| IV 1 | (= Ciphertext 3)
| Plaintext 4 | <=====> | Ciphertext 4 |
| Plaintext 5 | <=====> | Ciphertext 5 |
Obviously this decreases the efficiency with which the data is stored on the server side as edits accumulate.
Alternatively, you could use a mode that is used for encrypted filesystems, like XTS
mode. This involves breaking your text up into updateable sectors that are larger than a ciphertext block.
精彩评论