我最近发现了以下nifty little site,用于为外部加载的资源生成SubResource Integrity(SRI)标记。例如,输入最新的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,我发现了
完整性值可以包含由空格分隔的多个哈希。如果资源与其中一个哈希值匹配,则将加载该资源。
但这种匹配究竟是如何进行的呢?在一篇SO帖子中提出多个问题的时间......
integrity
和<script>
旁边的任何标签上使用<link>
属性。我特别想知道像<img>
,<source>
等多媒体标签。
- 浏览器是否首先尝试匹配最长的哈希,因为它更安全,或者最短的首先,因为它更快?
根据https://w3c.github.io/webappsec-subresource-integrity/#agility,“用户代理将选择列表中最强的哈希函数”。
- 人们真的会期望一个哈希匹配而不是全部三个?
不。但是就浏览器的行为而言:如果最强的哈希匹配,那么浏览器会使用它并忽略其余的(所以无论其他人是否也匹配都无关紧要)。
- 提供所有三个哈希而不是一个哈希有什么好处吗?
据我所知,在实践中目前没有任何好处。这是因为根据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类似,如果您只提供一个哈希值,您应该使用哪个?
据我所知,SHA-512值。
我通常会在其示例代码中看到提供sha384值的网站(例如,Bootstrap)。是因为它在中间,不是太大,不是太小?
Dunno为什么选择这样做。但是由于浏览器需要支持SHA-512哈希,所以你不会通过指定SHA-384哈希获得任何东西 - 事实上你只是失去了拥有最强哈希函数的价值。
- 出于好奇,可以在
integrity
和<script>
旁边的任何标签上使用<link>
属性。
不,它不可能 - 还没有。
我特别想知道像
<img>
,<source>
等多媒体标签。
SRI的计划一直是最终用于它的。如https://w3c.github.io/webappsec-subresource-integrity/#verification-of-html-document-subresources所述:
注意:此规范的未来版本可能包括对所有可能的子资源的完整性支持,即
a
,audio
,embed
,iframe
,img
,link
,object
,script
,source
,track
和video
元素。
......但我们还没有在那个未来。