V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Explr
V2EX  ›  信息安全

如果手工对 AES-GCM 算法的明文(和密文)分段,用上一段的 Authentication tag 作为下一段的 Associated data,是否会带来额外安全风险?

  •  
  •   Explr · 2021-04-18 15:27:37 +08:00 · 1748 次点击
    这是一个创建于 1321 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求是这样的,用.NET 和带认证(AEAD)的算法加密合理长度的文件(几 KB 到一二百 G 不等)。

    问题是:

    我不可能把整个文件都加载进内存,一次性传给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 重复问题)

    7 条回复    2021-04-18 21:21:05 +08:00
    billlee
        1
    billlee  
       2021-04-18 16:34:57 +08:00
    1. associated data 不是必须的,如果没有不需要加密、但需要 authentication 的数据,就不用传
    2. 流式解密没有问题,最后如果检验 tag 不成功,再回退(在文件加密的场景就是删除解密出来的文件)就行了。
    3dwelcome
        2
    3dwelcome  
       2021-04-18 16:52:32 +08:00
    "对第 n 段加密操作产生的 Authentication tag,作为 n+1 段的 Associated data 。"

    Authentication tag 目的是验证 Associated data 是否正确,就好比对 Associated data 进行一次散列化操作,解密时验证一次 Authentication tag, 看 Associated data 和加密内容里,有没有遭到修改。

    正常来说,TLS 官方推荐的 Associated data 都是用序列号,没听说过直接用上一次散列值的。就好比 SHA1()安全性和 SHA1(SHA1())安全性来比较,这样用好像也没什么特别的意义。
    3dwelcome
        3
    3dwelcome  
       2021-04-18 17:01:54 +08:00
    "3.使用每一段的序号作为加密这一段时使用的 nonce 。"

    我看 TLS 协议里,AEAD 算法的 nonce,用的都是 unpredictable IV, 也就是随机数,不知道你用序列号来替代,有没有问题。
    xiangyuecn
        4
    xiangyuecn  
       2021-04-18 17:05:23 +08:00
    你在想加密 1 个 1MB 的数据很安全,但加密 1000 个 1MB 的数据不安全😂

    想什么呢,分段加密就完了,一个安全个个安全,一个不安全个个不安全👌
    Rheinmetal
        5
    Rheinmetal  
       2021-04-18 17:17:00 +08:00
    没有 Associate Data 的话为啥要用 GCM ?
    Halry
        6
    Halry  
       2021-04-18 20:22:06 +08:00 via Android
    建议直接 ctr 后加 cmac,或者 ctr 后加 hash 就好
    gcm 好像就是为了能并行计算产生的,没的并行计算没有必要搞 gcm
    Explr
        7
    Explr  
    OP
       2021-04-18 21:21:05 +08:00
    感谢大佬们
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2540 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 04:48 · PVG 12:48 · LAX 20:48 · JFK 23:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.