AES256-GCM可以在https://gist.github.com/cannium/c167a19030f2a3c6adbb5a5174bea3ff
中实施但是,接口Seal
的{{1}}方法具有签名:
cipher.AEAD
因此,对于非常大的文件,必须将所有文件内容读入内存,这是不可接受的。
一种可能的方法是在Seal(dst, nonce, plaintext, additionalData []byte) []byte
和Reader
上实施Writer
/ Seal
接口,但不应该通过AEAD的那些分组密码“模式”来解决?所以我想知道这是golang cipher lib的设计错误,还是我错过了GCM的重要内容?
答案 0 :(得分:2)
AEAD不应该用于一次加密大量数据。 API旨在阻止这种情况。
在单个操作中加密大量数据意味着a)所有数据必须保存在内存中或b)API必须通过返回未经身份验证的明文以流式方式运行。
返回未经身份验证的数据是危险的not
hard,因为gpg命令还提供了流媒体界面,因此可以在互联网上查找人员gpg -d your_archive.tgz.gpg | tar xz
之类的内容。
对于像AES-GCM这样的结构,它当然非常容易 如果应用程序没有,则随意操纵明文 在处理之前验证它。即使申请很小心 在真实性发生之前不要将明文“释放”到UI 建立后,流媒体设计暴露出更多的程序攻击面。
通过规范化大型密文并因此流式传输API,下一步 随之而来的协议更有可能在没有意识到的情况下使用它们 问题因而问题仍然存在。
优选地,明文输入将被分块为相当大的 部件(比如16KiB)和单独加密。块只需要 足够大以至于其他验证者的开销是 可以忽略不计。通过这种设计,可以逐步增加大量消息 处理时无需处理未经验证的明文,以及 AEAD API可以更安全。 (更不用说更大的消息可以了 自AES-GCM以来处理的一个,对单个进行64GiB限制 明文。)
需要一些想法来确保块是正确的 顺序,即通过计数nonce,第一个块应该是第一个,即通过在零开始nonce,并且最后一个块应该是 最后,即通过附加一个特殊的空的终结器块 其他数据。但这并不难。
有关示例,请参阅miniLock中使用的分块。
即使有这样的设计,攻击者仍然可以造成这种情况 要被可检测地截断的消息。如果你想瞄准更高,一个 可以使用全有或全无变换,但这需要两个 传递输入,并不总是可行。
答案 1 :(得分:0)
这不是设计错误。只是在这方面API不完整。
GCM是一种流式操作模式,因此能够在不停止流的情况下按需处理加密和解密。您似乎无法在先前的MAC状态下重复使用相同的AEAD实例,因此您无法直接将此API用于GCM加密。
您可以在crypto.NewCTR
和您自己的GHASH实现之上实现自己的GCM。