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

如果 AES 无法用 GCM 模式,用明文 hash 作为 IV 以实现完整性校验是一个好的实现吗?

  •  
  •   drymonfidelia · 2 天前 · 1417 次点击
    17 条回复    2025-01-30 00:10:45 +08:00
    cnbatch
        1
    cnbatch  
       2 天前
    不如直接列出能用哪些模式
    leonshaw
        2
    leonshaw  
       2 天前
    不是
    geelaw
        3
    geelaw  
       2 天前 via iPhone
    ……这样得到的加密算法是确定性算法,所以不具有选择明文安全性,几乎不会使用。

    即使作为 DEM ,如果 hash 函数的 index 是公开的,在计数器模式下显然容易篡改,也几乎不可能使用。
    tool2dx
        4
    tool2dx  
       2 天前 via Android
    就算 Aes 的 iv 无效,只要 key 正确,都能解出后续加密信息。
    alphaControler
        5
    alphaControler  
       2 天前 via Android
    需要保证 IV 的安全性,不可被人获取才行的
    memorycancel
        6
    memorycancel  
       2 天前
    如果应用需要保护数据和消息,那么应该优先选择采用 SM4-GCM 模式.

    https://github.com/memorycancel/gmssl?tab=readme-ov-file#sm4_gcm-%E8%AE%A4%E8%AF%81%E5%8A%A0%E5%AF%86%E6%A8%A1%E5%BC%8F

    SM4 的 GCM 模式是一种认证加密模式,和 CBC 、CTR 等加密模式的主要区别在于,GCM 模式的加密过程默认在密文最后添加完整性标签,也就是 MAC 标签,因此应用在采用 SM4-GCM 模式时,没有必要再计算并添加 SM3-HMAC 了。在有的应用场景中,比如对消息报文进行加密,对于消息头部的一段数据(报头字段)只需要做完整性保护,不需要加密,SM4-GCM 支持这种场景。在 Sm4Gcm 类的 init 方法中,除了 key 、iv 参数,还可以提供 aad 字节数字用于提供不需要加密的消息头部数据。

    ```ruby
    key = "B789047EE36BD1DB9BCCD5B84D0E8C8D" # 16 bytes key
    iv = "F0F83C02897BE824AAB58361" # 12 bytes IV
    aad = "The_AAD_Data"
    input = "hello_sm4_gcm"
    encrypted_output, tag = SM4.gcm_encrypt(key, iv, aad, input)
    SM4.gcm_decrypt(key, iv, aad, encrypted_output, tag)
    #=> hello_sm4_gcm
    ```
    drymonfidelia
        7
    drymonfidelia  
    OP
       2 天前
    @alphaControler iv 不是只用来防止已知明文攻击,可以公开
    @cnbatch Unity 自带的 AES 不知道为什么用不了 GCM ,调用的时候会报错,CBC 那些模式好像都支持
    kenvix
        8
    kenvix  
       1 天前 via iPhone
    不行。IV 应该绝对随机,不应该从任何方式推导得到。可行的做法是自行做一个 HMAC 附加上去
    kenvix
        9
    kenvix  
       1 天前 via iPhone
    具体来说,发送端创建一个 ByteArray ,组成成分是
    密文的 HMAC + 随机 IV + AES-CTR 密文。接收端通过数组切片对密文做完整性验证,验证通过后用 IV+key 解密
    kk2syc
        10
    kk2syc  
       1 天前
    用 System.Security.Cryptography 可以 AES-GCM

    var key = new byte[32];
    RandomNumberGenerator.Fill(key);

    using var aes = new AesGcm(key);

    var nonce = new byte[AesGcm.NonceByteSizes.MaxSize]; // MaxSize = 12
    RandomNumberGenerator.Fill(nonce);

    var plaintextBytes = Encoding.UTF8.GetBytes("KK2SYC@V2EX");
    var ciphertext = new byte[plaintextBytes.Length];
    var tag = new byte[AesGcm.TagByteSizes.MaxSize]; // MaxSize = 16

    aes.Encrypt(nonce, plaintextBytes, ciphertext, tag);
    drymonfidelia
        11
    drymonfidelia  
    OP
       1 天前
    @kk2syc Unity 的 C#不支持,我测试了你这代码 Mono Il2cpp Windows Android 全都跑不起来
    PlatformNotSupportedException: Operation is not supported on this platform.
    System.Security.Cryptography.AesGcm..ctor (System.Byte[] key)
    kk2syc
        12
    kk2syc  
       1 天前
    @drymonfidelia 噢,请问你的 unity 和.NET 版本是多少?
    lysShub
        13
    lysShub  
       1 天前
    一般直接附加在密文后面,一起存储传输,不值得为那十几个 byte 走偏门
    busier
        14
    busier  
       1 天前 via iPhone
    效率不一定比 GCM 高 而且安全性还难保障
    drymonfidelia
        15
    drymonfidelia  
    OP
       1 天前
    @kk2syc
    Unity 2021.3 .NET 9.0
    最新版应该差不多,Unity 这几年没有什么大更新
    mitoop
        16
    mitoop  
       22 小时 49 分钟前
    加一个 hmac 是一个可行的方案,iv 还是保持随机,iv + 加密的字符串+hmac
    jim9606
        17
    jim9606  
       22 小时 25 分钟前
    Unity 默认的 .NET Standard 2.x profile 好像不支持 System.Security.Cryptography ,试下改成.NET 4.x profile 。
    不过我理解就算真不支持也不妨碍你去 nuget 找兼容 .NET Standard 的包补充这个功能。
    你说的 9.0 是 C#版本不是.NET 版本
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1977 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 14:36 · PVG 22:36 · LAX 06:36 · JFK 09:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.