正在缓存...

本文档适用于以下方法:

关于缓存

为了减少客户端带宽用量并保护 Google 免受流量高峰的影响,Lookup API 和 Update API 的客户端都需要创建和维护威胁数据的本地缓存。对于 Lookup API,缓存用于减少客户端向 Google 发送的 threatMatches 请求数量。对于 Update API,缓存用于减少客户端向 Google 发送的 fullHashes 请求的数量。下面概述了每个 API 的缓存协议。

Lookup API

Lookup API 的客户端应按照其 cacheDuration 字段定义的时长,对返回的每个 ThreatMatch 项进行缓存。然后,客户端需要在向服务器发出后续 threatMatches 请求之前查询缓存。如果之前返回的 ThreatMatch 的缓存时长尚未过期,客户端应假定该项仍不安全。缓存 ThreatMatch 项可能会减少客户端发出的 API 请求数量。

示例:threatMatches.find

点击表格标头中的请求和响应链接可查看完整示例。

网址检查
threatMatches 请求
网址匹配
threatMatches 响应
缓存行为
"threatEntries": [
 {"url": "http://www.urltocheck.org/"}
]
"matches": [{
 "threat": {"url": "http://www.urltocheck.org/"},
 "cacheDuration": "300.000s"
}]
匹配。
客户端必须等待 5 分钟才能发送包含网址 http://www.urltocheck.org/ 的新 threatMatches 请求。

Update API

为了减少使用 Update API 向 Google 发送的 fullHashes 请求总数,客户端必须维护本地缓存。该 API 建立了两种类型的缓存:正缓存和负缓存。

正缓存

为了防止客户端反复询问特定不安全完整哈希的状态,返回的每个 ThreatMatch 都包含一个正缓存时长(由 cacheDuration 字段定义),指示完整哈希被视为不安全的时长。

负缓存

为防止客户端反复询问特定安全完整哈希的状态,每个 fullHashes 响应都会为所请求前缀(由 negativeCacheDuration 字段定义)定义一个负的缓存时长。此时长表示对于所请求的列表,带有所请求前缀的所有完整哈希在多长时间内会被视为安全的,但服务器返回的不安全哈希除外。这种缓存尤为重要,因为它可以防止流量过载(可能因哈希前缀与接收大量流量的安全网址发生冲突而导致)。

咨询缓存

当客户端想要检查网址的状态时,会首先计算其完整哈希值。如果本地数据库中存在完整哈希的前缀,则客户端在向服务器发出 fullHashes 请求之前应查询其缓存。

首先,客户应检查缓存命中是否为正。如果相关完整哈希存在未过期的正缓存条目,则应将其视为不安全。如果正缓存条目已过期,客户端必须针对关联的本地前缀发送 fullHashes 请求。根据协议,如果服务器返回完整哈希,则视为不安全;否则,则视为安全。

如果没有针对完整哈希的正缓存条目,客户端应检查是否存在负缓存命中。如果关联的本地前缀存在未过期的排除缓存条目,则完整哈希会被视为安全。如果排除缓存条目已过期或不存在,客户端必须针对关联的本地前缀发送 fullHashes 请求,并按正常方式解读响应。

更新缓存

每当收到 fullHashes 响应时,都应更新客户端缓存。应根据 cacheDuration 字段为完整哈希创建或更新正向缓存条目。还应根据响应的 negativeCacheDuration 字段创建或更新哈希前缀的负缓存时长。

如果后续的 fullHashes 请求未返回当前正缓存的完整哈希,则客户端无需移除肯定缓存条目。这在实际操作中无需担心,因为正缓存持续时间通常很短(几分钟),以便快速纠正假正例。

示例场景

在以下示例中,假设 h(url) 是网址的哈希前缀,H(url) 是网址的完整长度哈希值。即 h(url) = SHA256(url).substr(4), H(url) = SHA256(url)。

现在,假设客户端(具有空缓存)访问了 example.com/,并看到 h(example.com/) 位于本地数据库中。客户端会请求哈希前缀 h(example.com/) 的完整长度哈希,然后接收完整长度哈希 H(example.com/) 以及正缓存时长(5 分钟)和负缓存时长(1 小时)。

正缓存持续时间为 5 分钟,可告知客户端在不发送其他 fullHashes 请求的情况下,必须将完整长度哈希 H(example.com/) 视为不安全的时长。5 分钟后,如果客户端再次访问 example.com/,则必须为该前缀 h(example.com/) 再发出一个 fullHashes 请求。客户端应根据新响应重置哈希前缀的负缓存时长。

1 小时的负缓存时长用于告知客户端,除了 H(example.com/) 之外,共用相同前缀 h(example.com/) 的所有其他完整哈希必须在多长时间内被视为安全。在 1 小时内,每个符合 h(网址) = h(example.com/) 的网址都必须被视为安全网址,因此不会产生 fullHashes 请求(假设 H(网址) != H(example.com/))。

如果 fullHashes 响应包含零匹配项,并且设置了负缓存时长,则在给定的负缓存时长内,客户端不得为所请求的任何前缀发出任何 fullHashes 请求。

如果 fullHashes 响应包含一个或多个匹配项,则系统仍会为整个响应设置负缓存时长。在这种情况下,单个完整哈希的缓存时长表示客户端必须认为该特定完整哈希在多长时间内不安全。ThreatMatch 缓存持续时间过后,如果请求的网址与缓存中的现有完整长度哈希匹配,客户端必须通过针对该哈希前缀发出 fullHashes 请求来刷新完整长度哈希。在这种情况下,负缓存时长不适用。响应的负缓存时长仅适用于 fullHashes 响应中不存在的完整长度哈希。对于响应中不存在的完整哈希,客户端必须在缓存期限负值过去之前避免发出任何 fullHashes 请求。

示例:fullHashes.find

点击表格标头中的请求和响应链接可查看完整示例。

哈希前缀
fullHashes 请求
全长度哈希匹配
完整哈希响应
缓存行为
"threatEntries": [
  {"hash": "0xaaaaaaaa"}
]
"matches": [],
"negativeCacheDuration": "3600.000s"
不匹配。
客户端不得在至少一小时内发送任何哈希前缀 0xaaaaaaaa 的 fullHashes 请求。 任何前缀为 0xaaaaaaaa 的哈希值在 1 小时内都是安全的。
"threatEntries": [
  {"hash": "0xbbbbbbbb"}
]
"matches": [
 "threat": {"hash": "0xbbbbbbbb0000..."}
 "cacheDuration": "600.000s",
],
"negativeCacheDuration": "300.000s"
可能匹配的结果。
客户端应将完整哈希 0xbbbbbbbb0000... 的网址视为不安全网址 10 分钟。客户端应考虑所有其他哈希前缀为 0xbbbbbbbb 的网址在 5 分钟内都是安全的。5 分钟后,哈希前缀的负缓存条目将过期。由于 0xbbbbbbbb0000... 的正缓存条目尚未过期,因此客户端应针对除哈希外的所有哈希发送 fullHashes 请求。
"threatEntries": [
  {"hash": "0xcccccccc"}
]
"matches": [
 "threat": {"hash": "0xccccccccdddd..."},
 "cacheDuration": "600.000s"
],
"negativeCacheDuration": "3600.000s"
可能匹配的结果。
客户端不得在至少 1h 内发送任何使用哈希前缀 0xcccccccc 的 fullHashes 请求,且必须假定该前缀是安全的,除非网址的完整哈希与缓存的完整哈希 0xccccccccdddd... 匹配。在这种情况下,客户端应在 10 分钟内将该网址视为不安全。完整长度的哈希值会在 10 分钟后过期。对该完整哈希的任何后续查询都应触发新的 fullHashes 请求。