AES256-GCM可以在https://gist.github.com/cannium/c167a19030f2a3c6adbb5a5174bea3ff中实现
但是,Seal
接口方法cipher.AEAD
具有签名:
Seal(dst, nonce, plaintext, additionalData []byte) []byte
因此,对于非常大的文件,必须将所有文件内容读入内存,这是不可接受的。
一种可能的方法是在和上实现Reader
/Writer
接口,但是难道不应该由AEAD的那些分组密码“模式”来解决吗?所以我想知道这是否是golang密码库的设计错误,还是我错过了GCM重要的东西?Seal
Open
不应使用AEAD一次性加密大量数据。API旨在阻止这种情况。
通过一次操作对大量数据进行加密意味着a)所有数据都必须保存在内存中,或者b)API必须通过返回未经身份验证的纯文本以流方式进行操作。
返回未经身份验证的数据很危险,在互联网上找到建议诸如此类的东西并不难,gpg -d your_archive.tgz.gpg | tar xz
因为gpg命令还提供了流接口。
当然,使用AES-GCM之类的结构,如果应用程序在处理之前不对明文进行身份验证,则很容易随意操纵明文。即使应用程序小心不要在确定了真实性之前才将纯文本“释放”到UI,流设计也会暴露更多的程序攻击面。
通过规范大密文并因此对API进行流处理,随之而来的下一个协议更可能在没有意识到问题的情况下使用它们,因此问题仍然存在。
优选地,纯文本输入将被分块为相当大的部分(例如16KiB)并分别进行加密。这些块仅需要足够大,以使来自其他认证器的开销可以忽略不计。通过这种设计,无需处理未经身份验证的纯文本就可以增量处理大型消息,并且AEAD API可以更安全。(更不用说可以处理更大的消息了,因为一个AES-GCM对单个纯文本有64GiB的限制。)
需要进行一些思考以确保块的顺序正确,即通过计数随机数,第一个块应在第一位,即通过将随机数从零开始,最后一个块应在最后,即通过添加一个空值。 ,带有特殊附加数据的终止符块。但这并不难。
有关示例,请参见miniLock中使用的分块。
即使采用这种设计,攻击者仍然可能导致邮件被可检测地截断。如果您想要更高的目标,则可以使用全有或全无的变换,尽管这需要对输入进行两次传递并且并不总是可行的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句