You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
v8_subtle_crypto.cc 文件是chromium 中用于实现 Web Crypto API 的前端代码之一,主要作用是实现 Web Crypto API 前端中一些与 V8 引擎交互的部分。具体来说, v8_subtle_crypto.cc 文件包含以下功能:
实现 V8 绑定: v8_subtle_crypto.cc 文件包含了与 V8 引擎相关的代码,用于将 Web Crypto API 的前端实现代码绑定到 V8 引擎中,从而可以在 JavaScript 中使用 Web Crypto API。在 v8_subtle_crypto.cc 文件中,使用 V8 的 FunctionTemplate 和 ObjectTemplate 类创建 JavaScript 对象和函数,并将它们绑定到 V8 引擎中。
处理 JavaScript 对象:在 JavaScript 中调用 Web Crypto API 方法时,会创建一些 JavaScript 对象和数组作为参数传递给底层的 C++ 实现。 v8_subtle_crypto.cc 文件中包含了将 JavaScript 对象和数组转换为 C++ 对象的代码,以及将 C++ 对象转换为 JavaScript 对象的代码。这些代码使用 V8 的 Local 和 Value 类型来处理 JavaScript 对象和值。
ScriptPromise SubtleCrypto::importKey(
ScriptState* script_state,
const String& raw_format,
const ArrayBufferOrArrayBufferViewOrDictionary& raw_key_data,
const AlgorithmIdentifier& raw_algorithm,
bool extractable,
const Vector<String>& raw_key_usages) {
// Method described by:// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-importKeyauto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
ScriptPromise promise = result->Promise();
// 解析传入的格式
WebCryptoKeyFormat format;
if (!CryptoKey::ParseFormat(raw_format, format, result))
return promise;
// 解析key用法
WebCryptoKeyUsageMask key_usages;
if (!CryptoKey::ParseUsageMask(raw_key_usages, key_usages, result))
return promise;
// In the case of JWK keyData will hold the UTF8-encoded JSON for the// JsonWebKey, otherwise it holds a copy of the BufferSource.
WebVector<uint8_t> key_data;
// 根据传入的格式,解析key,格式也就是上面列出来的formatswitch (format) {
// 14.3.9.2: If format is equal to the string "raw", "pkcs8", or "spki"://// (1) If the keyData parameter passed to the importKey method is a// JsonWebKey dictionary, throw a TypeError.//// (2) Let keyData be the result of getting a copy of the bytes held by// the keyData parameter passed to the importKey method.casekWebCryptoKeyFormatRaw:
casekWebCryptoKeyFormatPkcs8:
casekWebCryptoKeyFormatSpki:
if (raw_key_data.IsArrayBuffer()) {
key_data = CopyBytes(raw_key_data.GetAsArrayBuffer());
} elseif (raw_key_data.IsArrayBufferView()) {
key_data = CopyBytes(raw_key_data.GetAsArrayBufferView().View());
} else {
result->CompleteWithError(
kWebCryptoErrorTypeType,
"Key data must be a BufferSource for non-JWK formats");
return promise;
}
break;
// 14.3.9.2: If format is equal to the string "jwk"://// (1) If the keyData parameter passed to the importKey method is not a// JsonWebKey dictionary, throw a TypeError.//// (2) Let keyData be the keyData parameter passed to the importKey// method.casekWebCryptoKeyFormatJwk:
if (raw_key_data.IsDictionary()) {
// TODO(eroman): To match the spec error order, parsing of the// JsonWebKey should be done earlier (at the WebIDL layer of// parameter checking), regardless of the format being "jwk".if (!ParseJsonWebKey(raw_key_data.GetAsDictionary(), key_data, result))
return promise;
} else {
result->CompleteWithError(kWebCryptoErrorTypeType,
"Key data must be an object for JWK import");
return promise;
}
break;
}
// 14.3.9.3: Let normalizedAlgorithm be the result of normalizing an// algorithm, with alg set to algorithm and op set to// "importKey".// 解析传入的算法
WebCryptoAlgorithm normalized_algorithm;
if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationImportKey,
normalized_algorithm, result))
return promise;
HistogramAlgorithm(ExecutionContext::From(script_state),
normalized_algorithm);
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
ExecutionContext::From(script_state)
->GetTaskRunner(blink::TaskType::kInternalWebCrypto);
// 最终实现// WebCrypto CryptoPlatform::Current()->Crypto()->ImportKey(
format, std::move(key_data), normalized_algorithm, extractable,
key_usages, result->Result(), std::move(task_runner));
return promise;
}
经过分析可以发现,components/webcrypto 和 third_party/blink/renderer/modules/crypto 两个目录都包含与 Web Crypto API 相关的代码,但是它们的功能和作用有所不同。
components/webcrypto 目录包含了 chromium 浏览器中 Web Crypto API 的实现,包括算法实现、密钥管理和操作等。具体来说,该目录中包含了 algorithm_implementation.cc、algorithm_dispatch.cc、key_material.cc、operation.cc 等文件,用于实现各种加密算法和操作。
third_party/blink/renderer/modules/crypto 目录则包含了 chromium 中用于实现 Web Crypto API 的前端代码,包括 JavaScript 和 Web IDL 文件等。该目录中包含了 subtle_crypto.cc、subtle_crypto.h、subtle_crypto_algorithms.cc、subtle_crypto_algorithms.h 等文件,用于将 JavaScript 的调用转换为底层的 C++ 实现。
总的来说,components/webcrypto 目录实现了 Web Crypto API 的底层功能,而 third_party/blink/renderer/modules/crypto 目录则实现了 Web Crypto API 的前端调用接口。这两个目录的代码工作协同,提供了完整的 Web Crypto API 实现。
在 chromium 79.0.3945.130 版本中,components/webcrypto/algorithm_dispatch.cc 和 components/webcrypto/algorithm_implementation.cc 两个文件是用于实现 Web Crypto API 中各种算法的调度和实现。
chromium js加解密接口流程
js代码样例
首先看一下
chromium
如何调用js
加密接口,其中涉及异步调用,有两种方式。第一种
第二种
根据上面的代码首先来分析两个函数
window.crypto.subtle.importKey()
方法是Web Crypto API
中的一个方法,用于导入一个已有的密钥,并将其封装为CryptoKey
对象,以便进行加密、解密、签名和验证等操作。该方法接受四个参数:format
:一个字符串,指定要导入的密钥的格式。常见的格式有"raw"
、"pkcs8"
、"spki"
和"jwk"
。keyData
:要导入的密钥数据。根据不同的格式,keyData
可以是一个ArrayBuffer
、TypedArray
、DataView
、JsonWebKey
或类似的对象。algorithm
:一个对象,指定要使用的算法和参数。extractable
:一个布尔值,指定是否允许从导出的密钥中导出原始密钥材料。默认值为false
。使用
window.crypto.subtle.importKey()
方法,可以从不同的来源(如存储、网络等)导入现有的密钥,以便进行加密、解密等操作。导入的密钥可以是对称密钥或非对称密钥,具体取决于算法和数据格式。例如,可以从一个
Uint8Array
对象中导入一个AES
密钥,如下所示:在这个例子中,指定要导入一个
AES-CBC
算法的 128 位密钥,并且允许从导出的CryptoKey
对象中导出原始密钥材料。然后将Uint8Array
对象传递给window.crypto.subtle.importKey()
方法,该方法将密钥数据封装为CryptoKey
对象并返回。该对象可以用于加密、解密等操作。chromium源码分析
在
chromium
源码中,window.crypto.subtle.importKey()
方法的实现代码位于third_party/blink/renderer/modules/crypto/subtle_crypto.cc
文件中。具体来说,在
SubtleCrypto::importKey()
方法中,首先检查传入的参数是否合法,并根据传入的format
字符串解析密钥数据。如果format
是"jwk"
,则调用JSONParseObject
方法解析传入的 JSON 对象。如果format
是"raw"
,则将传入的密钥数据包装为一个scoped_refptr<SecureBlob>
对象。如果format
是"pkcs8"
或"spki"
,则调用crypto::ImportSubjectPublicKeyInfo()
或crypto::ImportPrivateKey()
方法解析密钥数据。解析密钥数据后,
SubtleCrypto::importKey()
方法根据传入的算法名称和参数,选择相应的密钥类型,并将密钥数据、算法和其他参数封装为一个CryptoKey
对象,并将其返回给调用方。这里有一个问题,就是js前端代码如何过渡到
subtle_crypto.cc
代码中,其实这里有个idl
文件定义了js
接口并规定了实现方式third_party/blink/renderer/modules/crypto/subtle_crypto.idl
根据这个文件
chromium
会在编译的过程中产生v8_subtle_crypto.h/v8_subtle_crypto.cc
文件v8_subtle_crypto.cc
文件是chromium
中用于实现Web Crypto API
的前端代码之一,主要作用是实现Web Crypto API
前端中一些与V8
引擎交互的部分。具体来说,v8_subtle_crypto.cc
文件包含以下功能:V8
绑定:v8_subtle_crypto.cc
文件包含了与V8
引擎相关的代码,用于将Web Crypto API
的前端实现代码绑定到 V8 引擎中,从而可以在JavaScript
中使用Web Crypto API
。在v8_subtle_crypto.cc
文件中,使用 V8 的FunctionTemplate
和ObjectTemplate
类创建JavaScript
对象和函数,并将它们绑定到 V8 引擎中。JavaScript
对象:在JavaScript
中调用Web Crypto API
方法时,会创建一些 JavaScript 对象和数组作为参数传递给底层的C++
实现。v8_subtle_crypto.cc
文件中包含了将JavaScript
对象和数组转换为C++
对象的代码,以及将C++
对象转换为JavaScript
对象的代码。这些代码使用V8
的Local
和Value
类型来处理JavaScript
对象和值。Promise
:Web Crypto API
中的一些方法返回的是Promise
对象,用于表示异步操作的结果。v8_subtle_crypto.cc
文件中包含了Promise
的实现代码,用于将底层的异步操作转换为JavaScript
中的Promise
。具体来说,v8_subtle_crypto.cc
文件中使用V8
的Promise::Resolver
类创建Promise
对象,并在异步操作完成后,调用Promise::Resolver
的Resolve()
方法将结果返回给JavaScript
。其中
v8_subtle_crypto.h
会引用subtle_crypto.h
,所以它连接了C++
源码的实现,这就定位到了window.subtle.crypto.importKey的C++实现,继续来看其importKey的具体实现(subtle_crypto.cc)分析完这部分代码可以发现,
subtle_crypto.cc
主要是解析传入的数据,但是最终的实现不在这里,经过分析,其最终的底层实现在**components/webcrypto
** 目录下的代码中在
components/webcrypto/webcrypto_impl.h
代码中以Encrypt为例分析
跟入**
algorithm_dispatch.cc
**分析后可以发现
algorigthm_registry.cc
中会注册在algorithm_implementations.h
中声明的各种加解密算法,具体的算法components/webcrypto/algorithms
以
AES-CBC
模式为例,其具体的加密实现在components/webcrypto/algorithms/aes_cbc.cc
其他说明
PostTask
在
chromium
中,PostTask
是一种用于在指定的线程上执行函数的机制。通常情况下,PostTask
用于在工作线程中执行任务,并将任务结果返回给主线程。具体来说,
PostTask
函数会将需要执行的函数包装成一个Task
对象,并将该对象添加到指定线程的任务队列中。一旦该线程空闲,就会从任务队列中取出Task
对象,并执行其中的函数。在
chromium
中,可以通过base::PostTask
函数和base::PostTaskWithTraits
函数来使用PostTask
机制。其中,PostTask
函数可以用于在指定线程上执行一般的函数,而PostTaskWithTraits
函数可以用于在指定线程上执行具有特定属性(例如优先级、延迟等)的函数。下面是一个示例,演示了如何使用
PostTask
函数在工作线程中执行任务并返回结果:在上面的代码中,
DoWork
函数会在工作线程中执行任务,并将任务结果打包成一个int
值。然后,它会通过base::PostTask
函数将OnWorkDone
函数打包成一个Task
对象,并将该对象添加到主线程的任务队列中。一旦主线程空闲,就会从任务队列中取出Task
对象,并执行其中的OnWorkDone
函数,从而处理任务结果。webcrypto/crypto区别
经过分析可以发现,
components/webcrypto
和third_party/blink/renderer/modules/crypto
两个目录都包含与 Web Crypto API 相关的代码,但是它们的功能和作用有所不同。components/webcrypto
目录包含了 chromium 浏览器中 Web Crypto API 的实现,包括算法实现、密钥管理和操作等。具体来说,该目录中包含了algorithm_implementation.cc
、algorithm_dispatch.cc
、key_material.cc
、operation.cc
等文件,用于实现各种加密算法和操作。third_party/blink/renderer/modules/crypto
目录则包含了 chromium 中用于实现 Web Crypto API 的前端代码,包括 JavaScript 和 Web IDL 文件等。该目录中包含了subtle_crypto.cc
、subtle_crypto.h
、subtle_crypto_algorithms.cc
、subtle_crypto_algorithms.h
等文件,用于将 JavaScript 的调用转换为底层的 C++ 实现。总的来说,
components/webcrypto
目录实现了 Web Crypto API 的底层功能,而third_party/blink/renderer/modules/crypto
目录则实现了 Web Crypto API 的前端调用接口。这两个目录的代码工作协同,提供了完整的 Web Crypto API 实现。在 chromium 79.0.3945.130 版本中,
components/webcrypto/algorithm_dispatch.cc
和components/webcrypto/algorithm_implementation.cc
两个文件是用于实现 Web Crypto API 中各种算法的调度和实现。algorithm_dispatch.cc
文件中包含一个名为DispatchAlgorithm
的函数,用于根据传入的Algorithm
对象调度合适的算法实现函数。该函数根据传入的算法名称和参数选择对应的算法实现函数,然后将控制权交给相应的实现函数进行处理。algorithm_implementation.cc
文件中包含了各种算法的实现函数,例如 AES、RSA、HMAC 等。这些函数使用传入的密钥、参数和数据执行加密、解密、签名、验证等操作,并返回相应的结果。这两个文件的作用是协同工作,使 Web Crypto API 能够支持多种加密算法和操作。在执行加密操作时,通过调用
DispatchAlgorithm
函数来选择合适的算法实现函数,然后由算法实现函数对数据进行处理,返回加密后的结果。在需要使用不同算法的情况下,只需要添加新的算法实现函数即可。The text was updated successfully, but these errors were encountered: