我正在制作一个note taking web app,可以在您输入时连续保存笔记。我发送差异以防止通过网络发送太多数据,当笔记是纯文本时,这种方法很好。
但是,我正在添加对加密笔记的支持,因此笔记只能以加密形式离开浏览器(因此笔记可以包含敏感信息,不会有任何人不知道密码短语(也永远不会离开浏览器)阅读它们,甚至没有完全访问数据库的人。但是,对笔记的所有更改当前都会完全更改加密文本,因此我必须在编辑时每隔一两秒将整个笔记发送回服务器。
根据我最近的阅读,我可以(但不应该)使用ECB block cipher加密模式,将明文分成16个字节的块并独立加密。这意味着如果编辑结束时(或者如果编辑添加或删除了16个字节的倍数),则差异将起作用。但是,在笔记中间发生的任何编辑都会影响笔记其余部分的加密文本。
所以,当我昨晚躺在床上时,我开始想知道是否存在“滚动块”加密算法,该算法根据周围的字符对注释的每个部分进行加密,以便更改/添加/删除任何一个字符只会改变16个周围的字节。希望这是有道理的。基本上,我想要一个加密算法,以便对明文进行微小的更改,对加密文本进行相当小的更改。
这样的算法是否存在? (它是否可以与AES一起使用的另一种分组密码操作模式,而不是一个完整的新算法?它的安全性与更常规的分组密码模式相比如何?)
我最初将此作为一个JavaScript问题,因为这是我最终想要的,但这可能会有点问题。
答案 0 :(得分:2)
您需要使用流密码操作模式,如CFB,OFB或CTR,而不是像ECB或CBC一样的块密码模式。见block ciphers modes of operation。您可以使用常见的加密算法,如AES和Blowfish。流式密码模式(如CTR)通常用于SSH等程序,因为您一次只能输入一个字符。
答案 1 :(得分:2)
您仍然可以使用CBC - 只需更新消息中间的一系列块,您就必须记住该序列中最后一个块的密文的旧值。例如,给定原始文本:
| 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 |
如果客户端想要更新块2和3,它使用Ciphertext 1
作为CBC的IV,并发送新的密文块Ciphertext 2b
和Ciphertext 3b
。然后,服务器将Ciphertext 3
保留为IV 1
,现在看起来像:
| 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 |
显然,当编辑累积时,这会降低数据在服务器端存储的效率。
或者,您可以使用用于加密文件系统的模式,例如XTS
模式。这涉及将文本分解为大于密文块的可更新扇区。