我不可能把整个文件都加载进内存,一次性传给AesGcm.Encrypt()方法。
但是.NET 库没有为 AES-GCM 提供流式操作方法。
(因为 AES-GCM 解密时,必须在所有块处理完毕后才能验证 Authentication tag 的有效性,而流式操作会在验证 Authentication tag 前返回解密后的明文。这时无法确定已经解密的部分是否曾遭到篡改,Github 讨论如下。)
https://github.com/dotnet/runtime/issues/23365
1.把文件切分成 1M 的数据段处理。
2.对于每个文件,使用唯一的 key 。
3.使用每一段的序号作为加密这一段时使用的 nonce 。
4.对第 n 段加密操作产生的 Authentication tag,作为 n+1 段的 Associated data 。第 1 段的 Associated data 使用 128 位 0 。
5.记录第 1 段的 Authentication tag 以启动加密过程,记录最后一段的 Authentication tag 以验证密文是否遭到篡改。
6.保证在最后一段验证完成前,除了写入到临时文件中,不对已经解密的文件进行任何处理。
tag1, cipherText1 = AES-GCM(plainText1, key, nonce=1, associatedData=0)
tag2, cipherText2 = AES-GCM(plainText2, key, nonce=2, associatedData=tag1)
...
tagN, cipherTextN = AES-GCM(plainTextN-1, key, nonce=n, associatedData=tagN-1)
然后 tag1,tagN,cipherText 1-N 作为密文存储。
这样操作除了失去并行计算能力外,是否会带来额外的脆弱性,使最终的安全性比一次性使用 AES-GCM 算法加密所有数据差?(不考虑文件大于 64GB 时一次性使用 AES-GCM 加密的 counter 重复问题)
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.