我正在LAMP堆栈上设计存储云软件。
文件可以有一个内部ID,但是在服务器文件系统中使用增量id作为文件名存储它们会有很多优点,但是使用哈希作为文件名。
如果应当对当前集中的数据库进行分片或分散或者应该设置某种主 - 主高可用性环境,那么作为数据库中的标识符的散列将具有很多优点。但我还不确定。
客户端可以在任何字符串下存储文件(通常是某种路径和文件名)。
这个字符串保证是唯一的,因为在第一级是类似“桶”的东西,用户可以在Amazon S3和Google存储中注册。
我的计划是将文件存储为客户端定义路径的哈希值。
这样,存储服务器可以直接提供文件,而不需要数据库询问它是哪个ID,因为它可以动态计算哈希值,从而计算文件名。
但我害怕碰撞。我目前考虑使用SHA1哈希。
我听说GIT也使用哈希值和修订标识符。
我知道碰撞的可能性非常低,但可能。
我无法判断这一点。你或者你不会为了这个目的而依赖哈希吗?
我还可以对路径的编码进行一些规范化。也许base64作为文件名,但我真的不希望这样,因为它可能变得混乱,路径可能会变得太长,可能还有其他复杂情况。
答案 0 :(得分:10)
假设你有一个具有“完美”属性的哈希函数,并假设加密哈希函数接近,那么适用的理论与适用于birthday attacks的理论相同。这就是说,给定最大数量的文件,您可以通过使用更大的散列摘要大小使碰撞概率尽可能小。 SHA有160位,因此对于任何实际数量的文件,冲突概率几乎为零。如果你查看链接中的表,你会发现一个128位散列,10 ^ 10个文件的冲突概率为10 ^ -18。
只要概率足够低,我认为解决方案是好的。与行星被小行星撞击的概率,磁盘驱动器中无法检测到的错误,在内存中翻转的位等等相比 - 只要这些概率足够低,我们就不会担心它们,因为它们“永远不会”发生。只要采取足够的余量,并确保这不是最薄弱的环节。
需要关注的一件事是哈希函数的选择以及它可能存在的漏洞。是否有其他身份验证或者用户只是提供路径并检索文件?
如果您考虑攻击者试图暴力破坏上面的场景,他们需要请求2 ^ 18个文件才能获得存储在系统中的其他随机文件(再次假设128位散列和10 ^ 10个文件,你将会有更少的文件和更长的哈希值。 2 ^ 18是一个相当大的数字,你可以强制这个速度受到网络和服务器的限制。在x尝试策略之后简单地锁定用户可以完全关闭此漏洞(这就是许多系统实现此类策略的原因)。建立一个安全的系统很复杂,需要考虑很多点,但这种方案可以非常安全。
希望这很有用......
编辑:另一种思考方式是,实际上每个加密或认证系统都依赖于某些事件的安全性很低的事件。例如我很幸运,可以猜测512位RSA密钥的主要因素,但系统不太可能被认为是非常安全的。答案 1 :(得分:1)
虽然碰撞的概率可能很小,但想象一下,如果碰巧发生哈希冲突,就会从一个客户向竞争对手提供一个高度机密的文件。
=业务结束
当发生碰撞时,我宁愿使用哈希来解决那些不那么重要的事情; - )
如果您有数据库,请将文件存储在GUID下 - 因此不是递增索引,而是适当的全局唯一标识符。它们在分布式分片/高可用性等方面运行良好。
想象一下最糟糕的情况,并假设它会在您作为一个惊人的创业公司在有线杂志中被推出一周之后发生......这对算法来说是一个很好的压力测试。