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

对于>256 字节的文件,对全文和尾部 128 位字节分别进行 xxHash3-128 然后拼接得到 256bit 散列和 SHA256 一次得到的 256bit 哪个更抗碰撞?用于命名用户上传的文件,另外加盐用拼接还是 XOR 方式更好?

  •  
  •   drymonfidelia · 16 天前 · 1823 次点击
    如果拼接的话,拼接在开头是不是要把原文 byte[]复制一遍,影响性能?我知道应用于签名场景的话不能拼接在末尾,因为 SHA256 可以向末尾追加块,但是应用于标题这个场景是否安全(会增加暴露盐值让 hash 值可预测)?如果通过将原文头部和盐 XOR 运算效果会不会更好? xxHash3 的 seed 可以代替盐吗?
    23 条回复    2025-07-20 15:20:36 +08:00
    drymonfidelia
        1
    drymonfidelia  
    OP
       16 天前
    总共有关联 6 个问题,没找到答案,于是想一起问。
    1. 对于>256 字节的文件,对全文和尾部 128 位字节分别进行 xxHash3-128 然后拼接得到 256bit 散列和 SHA256 一次得到的 256bit 哪个更抗碰撞?
    2. 用于命名用户上传的文件,另外加盐用拼接还是 XOR 方式更好?
    3. 如果拼接的话,拼接在开头是不是要把原文 byte[]复制一遍,影响性能?
    4. 我知道应用于签名场景的话不能拼接在末尾,因为 SHA256 可以向末尾追加块,但是应用于标题这个场景是否安全(会增加暴露盐值让 hash 值可预测)?
    5. 如果通过将原文头部和盐 XOR 运算效果会不会更好?
    6. xxHash3 的 seed 可以代替盐吗?
    my3157
        2
    my3157  
       16 天前 via Android
    为啥不直接用 uuid ,如果想去重的话,这种方式是不够的
    drymonfidelia
        3
    drymonfidelia  
    OP
       16 天前
    @my3157 想去重同时还可以通过文件名直接校验文件完整性
    drymonfidelia
        4
    drymonfidelia  
    OP
       16 天前
    @my3157 另外随机文件名的场景也不太适合用 UUID 吧,case insensitive 的文件名可以[0-9a-z],UUID 只使用了[0-9a-f]有点浪费空间,用 UUID 的话要再 base32 编码一下,直接随机[0-9a-z]会不会更合适
    mhycy
        5
    mhycy  
       16 天前
    把文件尺寸带上去,从碰撞上看带上尺寸更有用。
    hefish
        6
    hefish  
       16 天前
    把随机数带上,把时间带上,把鼠标滑过的坐标带上。。。把说话声音带上。。。。
    geelaw
        7
    geelaw  
       16 天前   ❤️ 3
    1. 把 xxHash3-128 和 SHA-256 对比还挺滑稽的,因为 xxHash3 从未为密码学设计,而安全性是全称命题(感性认知上属于不刻意设计就很可能不存在的性质)。

    2. 不理解什么是用 XOR 加盐,但我能想象的最简单的方式( XOR 消息之后散列,或者 XOR 散列值,或者两者都做)都很糟糕。

    3. 大多数 hash 算法都支持流式喂送数据,你只要调用两次名字类似 AppendData / Update 的方法就行了。

    4. 不太确定你想象中的“签名”是什么。如果你说的是 HMAC ,首先这是 MAC 而不是签名,然后 HMAC 和简单 hash 区别很大。

    5. 见 3.

    6. 见 1.

    另外,盐是散列函数索引 (hash key/index, or "seed" sometimes) 的实践表现,每个散列函数使用独立的 seed 从可证明安全角度自然没有“再加盐”的必要。
    seansong
        8
    seansong  
       16 天前
    如果要性能,考虑 HighwayHash ,做 256 位输出,要安全性,考虑 Blake3 做 256 位,拼接其他东西没啥意义
    ETiV
        9
    ETiV  
       16 天前 via iPhone
    1. 绝大多数同一个域名下的网页用你这个头尾算法都会冲突…前面都是 <DOCTYPE html>html head style 、尾巴可以是 Google 分析的 script /body /html 很容易凑齐

    2. 可以参考 git-lfs 的做法,gitlab github 都在用,它要存的文件肯定比你的多。sha256 做文件路径/文件名,同时记录所属关系

    3 往后看不太懂了…抱歉
    ZRS
        10
    ZRS  
       15 天前 via iPhone
    建议说原始需求
    laminux29
        11
    laminux29  
       15 天前
    file size + xxHash3 足以去重 + 扛碰撞, 而且只需要对 file size 相同的文件计算 xxHash3 。

    但是,计算文件的 xxHash3 时,就不能偷懒了,无论文件有多大,都必须计算整个文件的 xxHash3 。
    ysc3839
        12
    ysc3839  
       15 天前
    SHA256 即可,因为 SHA256 是专门设计用于完整性验证的,并且目前 SHA256 应该是没有已知的碰撞案例。
    xuanbg
        13
    xuanbg  
       15 天前
    @drymonfidelia 去重就够了,通过文件名校验文件完整性???这也是人能想得出来的? hash 值作为文件名或者一部分?难道你这个文件存在那里会有人去修改吗?
    msg7086
        14
    msg7086  
       15 天前
    我觉得碰撞空间相同的话随机碰撞概率应该一样吧。
    如果是刻意构造碰撞的话,更安全的算法应该更安全()
    diivL
        15
    diivL  
       15 天前
    SHA512
    liuidetmks
        16
    liuidetmks  
       15 天前
    1. 使用标准的加密做法,不要自创加密算法和协议 ,参考前两天热帖,op 自创了端到端加密,结果被人指出业余,不专业
    2. 直接说出原始需求,你一次提 6 个问题,看完都费劲,更别说解答了

    http://www.catb.org/~esr/faqs/smart-questions.html
    moonlord
        17
    moonlord  
       15 天前
    想要引入外部随机变量,想要安全的 256 bit 哈希算法?
    你是否在找 HMAC-SHA256 ?
    cybort
        18
    cybort  
       14 天前 via Android
    建议第一遍都存下来,文件名纯随机,hash 也存下来,后面发现 hash 相同的文件,再全文比对,如果来不及在线比对,可以事后去重
    kxuanobj
        19
    kxuanobj  
       14 天前
    只懂一点密码学的知识,只能回答两个问题。
    1. 对于>256 字节的文件,对全文和尾部 128 位字节分别进行 xxHash3-128 然后拼接得到 256bit 散列和 SHA256 一次得到的 256bit 哪个更抗碰撞?
    SHA256 。正常数据尾部 128 字节的熵必然低于 2^128 ,而只要是个正常的 128 位 hash 算法,它的输出的熵几乎接近 2^128 。你这个操作相当于降低信息熵,故意提高碰撞概率。
    怕恶意碰撞,请用两种不同 HASH 算法同时计算,比如 SHA3-256+BLAKE2s 。

    4. 我知道应用于签名场景的话不能拼接在末尾,因为 SHA256 可以向末尾追加块,但是应用于标题这个场景是否安全(会增加暴露盐值让 hash 值可预测)?
    怕原文被修改请使用 SHA3 类算法。
    drymonfidelia
        20
    drymonfidelia  
    OP
       12 天前
    @xuanbg 网络传输的时候可能出的情况太多了,被中间人、CDN 篡改之类的,客户端能根据链接直接判断文件是否被篡改,不然数据模型除了 id 外还要单独加个 hash 字段
    @geelaw 为什么用 XOR 加盐是很糟糕的设计?是简单的 salt 可能会导致加盐之后的原文被碰撞出来吗,直接拼接好像也存在这个问题,例如弱密码场景盐 123456 原文 aaabbb ,拼接后的 123456aaabbb 一样随便一个免费彩虹表都能查出来。在这个场景下,123456 xor aaabbb = PSRVWT 熵更高,如果再加长一点就不会出现在彩虹表
    @mhycy
    @laminux29 为什么这么多人提到要把文件大小加入 hash 计算呢? SHA256 是可以长度扩展计算的,如果要故意碰撞,只要随机最后一块就可以,按我的理解碰撞大文件和小文件的难度是一样的,不知道我的理解对不对
    xuanbg
        21
    xuanbg  
       12 天前
    @drymonfidelia 你怕传输过程被篡改、中间人攻击啥的,那应该对传输过程加密。不然你的用户文件落地就坏了,而且还不知道,等到用的时候才知道坏了,还有救吗?这种文件还存那做什么???

    别自己整不靠谱的山寨方案了,密码学只是应用的话还是很简单的。
    laminux29
        22
    laminux29  
       12 天前
    @drymonfidelia

    提文件大小,是因为计算 HASH 的代价很大,而且现实中,只有极少的文件,文件大小才会相似。所以,先对比文件大小,文件大小不一样,就不需要计算 HASH ,同时也防止了你说的那种碰撞。

    另外,防碰撞依赖的是算法的安全性以及 HASH 的长度,与文件大小没啥关系。
    mhycy
        23
    mhycy  
       12 天前
    @drymonfidelia 不是把文件大小加入 hash 而是把文件大小+hash 作为独立的文件名,hash 是额外的。这本质上是把碰撞概率拉低几个数量级的行为。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1549 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:45 · PVG 00:45 · LAX 09:45 · JFK 12:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.