computed_hashes.json
computed_hashes.json
计算扩展中包含的文件块的 SHA256 哈希值,这可能用于文件完整性和/或安全目的,以确保文件没有被损坏/篡改。
我深入探讨这个问题这个 StackOverflow 答案 https://stackoverflow.com/a/72891514/1137085,我在其中引用了 Chromium 源代码中的各个相关部分。
主要相关文件有:
- extensions/browser/computed_hashes.h https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/computed_hashes.h?q=computed_hashes
- extensions/browser/computed_hashes.cc https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/computed_hashes.cc?q=computed_hashes
其中,主要相关功能是:
- Compute https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/computed_hashes.cc;l=195-234?q=computed_hashes
- ComputeAndCheckResourceHash https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/computed_hashes.cc;l=326-340?q=computed_hashes
- GetHashesForContent https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/computed_hashes.cc;l=294-323?q=computed_hashes
实际的哈希计算可以在ComputedHashes::GetHashesForContent https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/computed_hashes.cc;l=294-323?q=computed_hashes功能。
verified_contents.json
简答
这用于文件完整性和/或安全目的,以确保扩展文件没有被损坏/篡改。
verified_contents.json
确保 Base64 编码payload
of the signed_content
对象内的对象具有description
of treehash per file
验证针对signature
内的物体的signatures
有一个header.kid
of webstore
。这是使用验证的crypto::SignatureVerifier::RSA_PKCS1_SHA256
跨越串联值protected
+ .
+ payload
.
如果签名验证正确,则将计算并比较扩展中包含的文件块的 SHA256 哈希值computed_hashes.json
(如上所述)。
深入解释
确定如何的内部细节verified_contents.json
创建/验证后,我们可以在 chromium 源代码中搜索verified_contents
如下:
- https://source.chromium.org/search?q=verified_contents https://source.chromium.org/search?q=verified_contents
这会返回许多有趣的文件,包括:
- extensions/browser/verified_contents.h https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.h?q=verified_contents
- extensions/browser/verified_contents.cc https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.cc?q=verified_contents
寻找verified_contents.h
我们可以看到一条描述其目的的评论verified_contents.json
,以及网上商店如何创建它:
// This class encapsulates the data in a "verified_contents.json" file
// generated by the webstore for a .crx file. That data includes a set of
// signed expected hashes of file content which can be used to check for
// corruption of extension files on local disk.
我们还可以看到许多函数原型,听起来像是用于解析和验证verified_contents.json
file:
// Returns verified contents after successfully parsing verified_contents.json
// file at |path| and validating the enclosed signature. Returns nullptr on
// failure.
// Note: |public_key| must remain valid for the lifetime of the returned
// object.
static std::unique_ptr<VerifiedContents> CreateFromFile(
base::span<const uint8_t> public_key,
const base::FilePath& path);
// Returns verified contents after successfully parsing |contents| and
// validating the enclosed signature. Returns nullptr on failure. Note:
// |public_key| must remain valid for the lifetime of the returned object.
static std::unique_ptr<VerifiedContents> Create(
base::span<const uint8_t> public_key,
base::StringPiece contents);
// Returns the base64url-decoded "payload" field from the |contents|, if
// the signature was valid.
bool GetPayload(base::StringPiece contents, std::string* payload);
// The |protected_value| and |payload| arguments should be base64url encoded
// strings, and |signature_bytes| should be a byte array. See comments in the
// .cc file on GetPayload for where these come from in the overall input
// file.
bool VerifySignature(const std::string& protected_value,
const std::string& payload,
const std::string& signature_bytes);
我们可以在以下位置找到这些函数的定义verified_contents.cc
:
-
VerifiedContents::CreateFromFile https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.cc;l=82-109?q=verified_contents calls base::ReadFileToString https://source.chromium.org/chromium/chromium/src/+/main:base/files/file_util.cc;l=296-312(然后调用
ReadFileToStringWithMaxSize
将文件作为二进制文件读取,模式为rb
) 加载文件的内容,然后将其传递给Create https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.cc;l=111-197?q=verified_contents
-
VerifiedContents::Create https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.cc;l=111-197?q=verified_contents
- calls VerifiedContents::GetPayload https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.cc;l=213-316提取/验证/解码 Base64 编码的内容
payload
场内verified_contents.json
(有关更深入的解释,请参阅下文)
- 将其解析为 JSONbase::JSONReader::Read https://source.chromium.org/chromium/chromium/src/+/main:base/json/json_reader.cc;l=66-79
- 提取出
item_id
键,验证它crx_file::id_util::IdIsValid https://source.chromium.org/chromium/chromium/src/+/main:components/crx_file/id_util.cc;l=90-102,并将其添加到verified_contents
as extension_id_
- 提取出
item_version
键,验证它Version::IsValid() https://source.chromium.org/chromium/chromium/src/+/main:base/version.cc,并将其添加到verified_contents
as version_
- extracts all of the
content_hashes
objects and
- 验证
format
每一个都是treehash
- 提取出
block_size
and hash_block_size
,确保它们具有相同的值,并添加block_size
to verified_contents
as block_size_
- extracts all of the
files
objects
- 提取出
path
and root_hash
键并确保root_hash
Base64 可解码
- 计算
canonical_path
using content_verifier_utils::CanonicalizeRelativePath https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_verifier_utils.cc;l=25-34 and base::FilePath::FromUTF8Unsafe https://source.chromium.org/chromium/chromium/src/+/main:base/files/file_path.cc;l=653-656,并将其插入到root_hashes_
in the verified_contents
- 最后,返回
verified_contents
-
VerifiedContents::GetPayload https://source.chromium.org/chromium/chromium/src/+/main:base/json/json_reader.cc;l=66-79
- 解析
contents
作为 JSON 与base::JSONReader::Read https://source.chromium.org/chromium/chromium/src/+/main:components/crx_file/id_util.cc;l=90-102
- finds an object in the JSON that has the
description
key set to treehash per file
- extracts the
signed_content
object
- extracts the
signatures
array
- finds an object in the
signatures
array that has a header.kid
set to webstore
- 提取出
protected
/ signature
键和 Base64 解码signature
into signature_bytes
- 提取出
payload
key
- calls VerifySignature https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.cc;l=318-342 with
protected
/ payload
/ signature_bytes
- 如果签名有效,则 Base64 解码
payload
转换为 JSON 字符串
-
VerifiedContents::VerifySignature https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/verified_contents.cc;l=318-342
- calls SignatureVerifier::VerifyInit https://source.chromium.org/chromium/chromium/src/+/main:crypto/signature_verifier.cc;l=26-81 using
crypto::SignatureVerifier::RSA_PKCS1_SHA256
- 用这个来验证
protected_value
+ .
+ payload
由于这没有显示文件哈希本身是如何验证的,所以我然后搜索了哪里VerifiedContents::CreateFromFile
被称为:
- https://source.chromium.org/search?q=VerifiedContents::CreateFromFile https://source.chromium.org/search?q=VerifiedContents::CreateFromFile
这向我指出了以下文件:
- extensions/browser/content_verifier/content_hash.cc https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_hash.cc?q=VerifiedContents::CreateFromFile
Where
-
VerifiedContents::CreateFromFile
被称为ReadVerifiedContents https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_hash.cc;l=46-62?q=VerifiedContents::CreateFromFile
-
ReadVerifiedContents
被称为ContentHash::GetVerifiedContents https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_hash.cc;l=169-192?q=VerifiedContents::CreateFromFile,当内容验证成功后,会将其传递给verified_contents_callback
-
GetVerifiedContents
被称为ContentHash::Create https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_hash.cc;l=89-110?q=VerifiedContents::CreateFromFile,通过ContentHash::GetComputedHashes https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_hash.cc;l=264-288 as the verified_contents_callback
-
ContentHash::GetComputedHashes
calls ContentHash::BuildComputedHashes https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_hash.cc;l=391-457
-
ContentHash::BuildComputedHashes
将读取/创建computed_hashes.json
通过调用文件file_util::GetComputedHashesPath https://source.chromium.org/chromium/chromium/src/+/main:extensions/common/file_util.cc;l=553-555, ComputedHashes::CreateFromFile
, CreateHashes https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/content_verifier/content_hash.cc;l=354-389(这称为ComputedHashes::Compute https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/computed_hashes.cc;l=195-234), etc
注意ComputedHashes::CreateFromFile
and ComputedHashes::Compute
是描述的功能computed_hashes.json
上面的部分(用于计算扩展中包含的文件块的 SHA256 哈希值),我将在这个 StackOverflow 答案 https://stackoverflow.com/a/72891514/1137085.