IPFS,关于面向未来的加密哈希

  • 原创:PASCAL PRECHT

    我们来谈谈哈希!

    正如在新的开始帖子中提到的那样,我想记录我的学习情况。因为我正在深入研究分布式存储领域中,能够引起我注意的项目,例如IPFS。如果您不熟悉IPFS或者没有听说过它,它基本上是一堆(网络)协议,它使完全分布式文件存储系统,能够创建出更快、更安全、更可靠的Web。

    哈希在IPFS中发挥着重要作用,因为它们用于处理分布式网络中的内容,类似于Git如何使用哈希来处理存储库中的提交、树和二进制对象(您可能每天都使用它们,而不会注意到)。

    当系统依赖加密哈希作为基本构建块时,考虑到使用的哈希算法在某些时候被认为是弱的或不安全的,考虑更新策略是非常重要的。在这篇文章中,我想探讨IPFS项目如何利用“Multihashes”来确保哈希值是可升级的,并且可以在同一个应用程序中共存。

    那么......什么是哈希呢?

    让我们来快速解决这个问题。哈希实际上不如听起来那么可怕。它实际上只是一个函数,它接受一些任意输入并返回一个固定大小的字母数字字符串。字母数字字符串的外观取决于给定的哈希算法。

    让我们组成一个简单的哈希函数,并说我们有一条消息“abc”,这是我们输入的。我们的自定义散列函数的算法获取输入消息的每个字符,并将其向前移动三个字母。这将导致哈希摘要“def”。

    HASH('abc') // 'def'

    它就是,哈希。

    现在,如果我们看一些真实世界的哈希函数,它们完全相同(只是算法显然更复杂)。例如,Git使用SHA-1,它产生160位散列,通常呈现为十六进制数,长度为40位。它散列原始内容(二进制数据)、树对象和提交。

    如果您的计算机上安装了Git,请自行尝试!只需运行以下命令:

    $ echo "abc" | git hash-object --stdin

    返回的摘要是8baef1b4abc478178b004d62031cf7fe6db6f903。是的,哈希算法将始终为给定输入返回相同的哈希值。这是您从发件人收到数据时验证完整性的方法。但是,无法从散列中导出输入。这是超级重要的特征。

    为了准确起见,事实证明Git实际上并不对原始输入进行散列,而是在输入blob之前预先跟随内容的大小,然后进行散列。现在这并不重要,但是如果您尝试使用OpenSSL的SHA-1实现来验证摘要,您会注意到它将从'abc'返回不同的哈希值。

    另外,如果你也想更深入了解(像我一样),可以看看这个Stack0verflow的答案。

    最重要是:

    • 哈希是算法将输入转换为摘要的结果

    • 算法返回固定长度(例如SHA1返回160位哈希值)

    • 它们总是为给定的输入返回相同的哈希值

    • 从散列中导出输入是(或应该)

    回到这个“Multihashes”的事情......

    哈希的问题

    哈希真的很棒!由于它们的特性,我们可以使用它们来验证内容和数据的完整性,此外,它们也可以非常紧凑。不幸的是,有时它们会变得不安全或不够强大(我正在看着的,MD5!),攻击者可以设法打破它们。虽然不是一直发生的事情,但事情还是会发生。

    想象一下,一个简单但常见的场景,其中用户密码存储在某个数据库中。显然,我们不想用纯文本存储密码,因为许多不同的原因,我认为这里没有必要提及,这将是一个灾难。哈希正确使用的用例?让我们假设把这些密码存储为MD5哈希。很好,很多问题通过简单的方法解决了。

    现在让我们假设说,第二天MD5被认为是不安全的。会怎么做?我们必须将哈希算法升级为更安全的东西。然而,这却是一个挑战,因为我们碰巧要处理一个大型的、或许是分布的系统,并且只能随时间进行升级。

    我们需要找到一种缓慢(但尽可能快)升级到不同哈希算法的方法,同时保持现有系统的正常运行。

    另一个不应引起注意的问题是,现有系统通常依赖于简单地假设某种类型的散列及其长度的API。想想有多少Git存储库,每个对象都是160位十六进制哈希(40位)。想象一下当Git切换到SHA-2时会发生什么,这是一个256位的哈希值以及有多少工具和应用程序会中断。

    通过引入版本控制系统,可以避免出现可以避免的问题。

    版本化的哈希

    这个想法很简单:引入一些版本作为哈希的一部分,这样系统就可以很容易地找出它正在处理的哈希。

    让我们采用我们之前使用Git计算的'abc'哈希:

    8baef1b4abc478178b004d62031cf7fe6db6f903

    如果这是哈希密码,并且我们必须验证它是否是正确的密码,我们只是将这个计算的哈希值与我们数据库中的哈希值进行比较。但是,如前所述,我们希望在不破坏系统的情况下迁移到不同的哈希算法。例如,与SHA-256相同的输入看起来完全不同:

    BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD

    为了预先知道我们实际上处理的是不同的哈希版本,我们可以引入这样的版本号:

    1:BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD

    这对于已经使用无版本哈希的系统也很有用。必须在版本更改之前创建任何没有冒号的哈希。任何具有冒号和版本号的哈希都可以以相应的方式处理(剥离前两个字节(1:)并假设哈希在这种情况下是SHA-256哈希)。

    该解决方案可以根据我们的需求以不同方式按比例放大和缩小。例如,如果我们遇到的情况是碰巧处理两种以上的哈希类型,我们可以为每种类型引入如下版本:

    sha1:0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7aeblake2:a96953281f3fd944a3206219fad61a40b992611b7580f1fa091935db3f7ca13d

    事实上,这是似乎正确的路径。

    我们可以做得更好。虽然上述方法是应对这一挑战的一种不错的方式,但仍有如下一些问题:

    • 一个明显的特征是版本类型可能与散列类型的其余部分不兼容。例如s,不是有效的十六进制数字。但是,大多数系统以十六进制(或base32,base64等)传输哈希值。因此,在这些方案之上构建应用程序时会增加复杂性。

    • 如果必须存储数百万或数十亿个哈希值,那么长版本类型blake2可能会在字节成本方面产生相当大的影响。较短的简化版本语法在这里可能会更好。

    接下来,正式开始深入了解Multihash。

    Multihashes

    这就是Multihashes发挥作用的地方。Multihash是一种协议(由IPFS使用),用于区分各种完善的哈希函数的输出。它与我们刚刚完成的工作非常相似,只是它以智能方式添加了一些额外的信息。

    Multihash具有以下模式:

    <hash-func-type><digest-length><digest-value>

    在哪些地方

    • 在<hash-func-type>描述中使用的哈希函数-有一个哈希表,看看代码是如何映射

    • 该<digest-length>描述的长度<digest-value>以字节为单位

    • 这<digest-value>是我们感兴趣的实际哈希值

    我们以下面的Multihash为例,尝试揭开它的神秘面纱

    122041dd7b6443542e75701aa98a0c235951a28a0d851b11564d20022ab11d2589a8

    注意:在十六进制代码中,两位数等于一个字节。换句话说,前两位数字12可以翻译成0001 0010。这就是十六进制代码中的160位散列是40位数的原因。此外,通常使用十六进制代码0x来表示它是十六进制代码。在这种情况下0x12,12是相同的事情。

    我们已经知道第一个字节标识了哈希函数类型。根据Mu1tihash表,那就是sha2-256。

    接下来,摘要长度(也以字节为单位)。0x20是32十进制的,所以此时我们已经知道以下哈希值是32字节(256位)长。

    这是一个重要的信息。还记得Git从SHA-1切换到SHA-256的场景吗?许多使用Git哈希的应用程序和系统都希望它们长160位。如果Git使用类似Multihash的东西,应用程序可以简单地读出预期散列的长度并保持变量。

    我们正在处理的实际哈希摘要

    41dd7b6443542e75701aa98a0c235951a28a0d851b11564d20022ab11d2589a8。

    非常酷,我们基本上有一个完全自我描述的哈希,并且仍然可以寻址,因为它保留了任何其他加密哈希的特征。

    现在使用Multihash协议也很容易。有几种语言的实现,如Go,Java,Rust,JavaScript等等!如果你想了解Multihashes和IPFS协议栈,这里有一些资源:

    • RFC:Juan Benet的面向未来的加密哈希值

    https://github.com/jbenet/random-ideas/issues/1)

    • 谈话:由Juan Benet进入Merkle Forest

    https://www.youtube.com/watch?v=Bqs_LzBjQyk)

    • Multihash网站

    https://multiformats.io/multihash/)

登录后回复
 

加微信进群交流

与 Filecoin中国社区 的连接断开,我们正在尝试重连,请耐心等待