最佳 SRI 哈希大小是多少?

What is the best SRI hash size?

我最近发现了以下 nifty little site for generating SubResource Integrity (SRI) Tags for externally loaded resources. For example, enterring the latest jQuery URL (https://code.jquery.com/jquery-3.3.1.min.js),其中之一得到以下 <script> 标签:

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8= sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT sha512-+NqPlbbtM1QqiK8ZAo4Yrj2c4lNQoGv8P79DPtKzj++l5jnN39rHA/xsqn8zE9l0uSoxaCdrOgFs6yjyfbBxSg==" crossorigin="anonymous"></script>

我了解 SRI 哈希的用途,我知道它们可以使用不同的哈希大小(256 位、384 位或 512 位),但我以前从未见过像这样同时使用这三种哈希值。深入研究 MDN docs,我发现

An integrity value may contain multiple hashes separated by whitespace. A resource will be loaded if it matches one of those hashes.

但是匹配究竟是如何进行的呢?一个 SO 中多个问题的时间 post...

  1. 浏览器是先匹配最长的哈希值,因为它更安全,还是先匹配最短的哈希值,因为它更快?
  2. 人们真的会期望 一个 哈希匹配而不是所有三个(除了开发人员错误输入哈希的微不足道的情况)吗?
  3. 提供所有三种哈希值而不是只提供一种哈希值有什么好处吗?
  4. 类似于#1,如果你只提供一个散列值,你应该使用哪个?我通常会看到网站(例如 Bootstrap)在其示例代码中提供 sha384 值。是不是因为它就在中间,不太大,也不太小?
  5. 出于好奇,integrity 属性是否可以用于 <script><link> 之外的任何标签。我特别想知道 <img><source> 等多媒体标签
  1. Do browsers attempt to match the longest hash first, since its more secure, or the shortest first, since its faster?

根据 https://w3c.github.io/webappsec-subresource-integrity/#agility,“用户代理将选择列表中最强的哈希函数”。

  1. Would one really ever expect for one hash to match and not all three?

没有。但就浏览器行为而言:如果最强的哈希值匹配,浏览器将使用它并忽略其余的(因此不管其他是否匹配也无所谓)。

  1. Is there any benefit to providing all three hashes instead of just one?

据我所知,在实践中没有 当前 好处。这是因为根据 https://w3c.github.io/webappsec-subresource-integrity/#hash-functions,“符合标准的用户代理必须支持 SHA-256、SHA-384 和 SHA-512 加密哈希函数”。

所以目前,如果您只指定一个 SHA-512 哈希,所有支持 SRI 的浏览器都会使用它。

但根据 https://w3c.github.io/webappsec-subresource-integrity/#agility 指定多个哈希的意图是 “以在面对未来的密码学发现时提供敏捷性……鼓励作者在可用时开始迁移到更强大的哈希函数” .

换句话说,在未来的某个时候,浏览器将开始添加对更强大的散列函数(基于 SHA-3 的散列函数 https://en.wikipedia.org/wiki/SHA-3 或其他)的支持。

因此,由于您需要继续针对较旧的浏览器和较新的浏览器,因此在一段时间内您会针对某些 SHA-512 是最强哈希函数的浏览器,同时针对当时出现的新浏览器,这些浏览器将增加对某些 SHA-3(或其他)哈希函数的支持。

所以在这种情况下,您需要在 integrity 值中指定多个哈希值。

  1. Similar to #1, If you only provide one hash value, which should you use?

SHA-512 值。

I typically see sites (e.g., Bootstrap) providing sha384-values in their example code. Is that because its right in the middle, not too big, not too small?

我不知道他们为什么选择那样做。但是,由于浏览器需要支持 SHA-512 哈希,因此通过指定 SHA-384 哈希不会获得任何好处 — 事实上,您只是失去了拥有可用的最强哈希函数的价值。

  1. Out of curiosity, can the integrity attribute be used on any tags beside <script> and <link>.

不,不可能——还没有。

I'm particularly wondering about multimedia tags like <img>, <source>, etc.

正如 https://w3c.github.io/webappsec-subresource-integrity/#verification-of-html-document-subresources 所解释的那样,SRI 的计划一直是最终也用于这些人 —

Note: A future revision of this specification is likely to include integrity support for all possible subresources, i.e., a, audio, embed, iframe, img, link, object, script, source, track, and video elements.

……但我们还没有进入那个未来。