说明
使用此 API 将证书公开给平台,平台可以使用这些证书进行 TLS 身份验证。
权限
certificateProvider
可用性
概念和用法
如需使用此 API 向 ChromeOS 公开客户端证书,通常需要按以下步骤操作:
- 该扩展程序会注册
onCertificatesUpdateRequested
和onSignatureRequested
事件。 - 扩展程序会调用
setCertificates()
,以在初始化后提供初始证书列表。 - 该扩展程序会监控可用证书列表中的更改,并调用
setCertificates()
以便在每次发生此类更改时通知浏览器。 - 在 TLS 握手期间,浏览器会收到客户端证书请求。通过
onCertificatesUpdateRequested
事件,浏览器会要求扩展程序报告其当前提供的所有证书。 - 扩展程序会使用
setCertificates()
方法报告当前可用的证书。 - 浏览器会将所有可用证书与远程主机发来的客户端证书请求进行匹配。系统会在选择对话框中向用户显示匹配项。
- 用户可以选择证书,从而批准或中止身份验证。
- 如果用户中止身份验证或没有证书与请求匹配,TLS 客户端身份验证将被中止。
- 否则,如果用户使用此扩展程序提供的证书批准身份验证,浏览器会请求该扩展程序对数据进行签名,以便继续 TLS 握手。请求会以
onSignatureRequested
事件的形式发送。 - 此事件包含输入数据,声明必须使用哪种算法生成签名,并引用此扩展程序报告的某个证书。扩展程序必须使用与所引用证书关联的私钥为给定数据创建签名。创建签名可能需要在实际签名之前附加 DigestInfo 并对结果进行填充。
- 扩展程序使用
reportSignature()
方法将签名发回给浏览器。如果无法计算签名,则必须在不带签名的情况下调用该方法。 - 如果已提供签名,浏览器会完成 TLS 握手。
实际步骤顺序可能会有所不同。例如,如果使用自动选择证书的企业政策,系统就不会要求用户选择证书(请参阅 AutoSelectCertificateForUrls
和面向用户的 Chrome 政策)。
在扩展程序中,这可能类似于以下代码段:
function collectAvailableCertificates() {
// Return all certificates that this Extension can currently provide.
// For example:
return [{
certificateChain: [new Uint8Array(...)],
supportedAlgorithms: ['RSASSA_PKCS1_v1_5_SHA256']
}];
}
// The Extension calls this function every time the currently available list of
// certificates changes, and also once after the Extension's initialization.
function onAvailableCertificatesChanged() {
chrome.certificateProvider.setCertificates({
clientCertificates: collectAvailableCertificates()
});
}
function handleCertificatesUpdateRequest(request) {
// Report the currently available certificates as a response to the request
// event. This is important for supporting the case when the Extension is
// unable to detect the changes proactively.
chrome.certificateProvider.setCertificates({
certificatesRequestId: request.certificatesRequestId,
clientCertificates: collectAvailableCertificates()
});
}
// Returns a private key handle for the given DER-encoded certificate.
// |certificate| is an ArrayBuffer.
function getPrivateKeyHandle(certificate) {...}
// Digests and signs |input| with the given private key. |input| is an
// ArrayBuffer. |algorithm| is an Algorithm.
// Returns the signature as ArrayBuffer.
function signUnhashedData(privateKey, input, algorithm) {...}
function handleSignatureRequest(request) {
// Look up the handle to the private key of |request.certificate|.
const key = getPrivateKeyHandle(request.certificate);
if (!key) {
// Handle if the key isn't available.
console.error('Key for requested certificate no available.');
// Abort the request by reporting the error to the API.
chrome.certificateProvider.reportSignature({
signRequestId: request.signRequestId,
error: 'GENERAL_ERROR'
});
return;
}
const signature = signUnhashedData(key, request.input, request.algorithm);
chrome.certificateProvider.reportSignature({
signRequestId: request.signRequestId,
signature: signature
});
}
chrome.certificateProvider.onCertificatesUpdateRequested.addListener(
handleCertificatesUpdateRequest);
chrome.certificateProvider.onSignatureRequested.addListener(
handleSignatureRequest);
类型
Algorithm
支持的加密签名算法类型。
枚举
"RSASSA_PKCS1_v1_5_MD5_SHA1"
使用 MD5-SHA-1 哈希指定 RSASSA PKCS#1 v1.5 签名算法。扩展程序不得添加 DigestInfo 前缀,而只能添加 PKCS#1 填充。此算法已废弃,从 Chrome 109 版开始,Chrome 将永远不会请求此算法。
"RSASSA_PKCS1_v1_5_SHA1"
使用 SHA-1 哈希函数指定 RSASSA PKCS#1 v1.5 签名算法。
"RSASSA_PKCS1_v1_5_SHA256"
使用 SHA-256 哈希函数指定 RSASSA PKCS#1 v1.5 签名算法。
"RSASSA_PKCS1_v1_5_SHA384"
使用 SHA-384 哈希函数指定 RSASSA PKCS#1 v1.5 签名算法。
"RSASSA_PKCS1_v1_5_SHA512"
使用 SHA-512 哈希函数指定 RSASSA PKCS#1 v1.5 签名算法。
“RSASSA_PSS_SHA256”
使用 SHA-256 哈希函数、MGF1 掩码生成函数和与哈希值大小相同的盐指定 RSASSA PSS 签名算法。
"RSASSA_PSS_SHA384"
使用 SHA-384 哈希函数、MGF1 掩码生成函数和与哈希大小相同的盐指定 RSASSA PSS 签名算法。
"RSASSA_PSS_SHA512"
使用 SHA-512 哈希函数、MGF1 掩码生成函数和与哈希大小相同的盐指定 RSASSA PSS 签名算法。
CertificateInfo
属性
-
证书
ArrayBuffer
必须是 X.509 证书的 DER 编码。目前,仅支持 RSA 密钥的证书。
-
supportedHashes
哈希[]
必须设置为此证书支持的所有哈希。此扩展程序只会被要求提供使用其中一种哈希算法计算的摘要的签名。应按哈希偏好顺序递减排列。
CertificatesUpdateRequest
属性
-
certificatesRequestId
数值
要传递给
setCertificates
的请求标识符。
ClientCertificateInfo
属性
-
certificateChain
ArrayBuffer[]
该数组必须将 X.509 客户端证书的 DER 编码作为其第一个元素。
此字段必须只包含一个证书。
-
supportedAlgorithms
此证书支持的所有算法。系统只会使用其中一种算法要求扩展程序提供签名。
Error
扩展程序可以报告的错误类型。
值
"GENERAL_ERROR"
Hash
已弃用。已被 Algorithm
替代。
枚举
“MD5_SHA1”
指定 MD5 和 SHA1 哈希算法。
“SHA1”
指定 SHA1 哈希算法。
“SHA256”
指定 SHA256 哈希算法。
“SHA384”
指定 SHA384 哈希算法。
“SHA512”
指定 SHA512 哈希算法。
PinRequestErrorType
可通过 requestPin 函数向用户显示的错误类型。
枚举
“INVALID_PIN”
指定 PIN 码无效。
“INVALID_PUK”
指定 PUK 无效。
"MAX_ATTEMPTS_EXCEEDED"
指定尝试次数已超出上限。
"UNKNOWN_ERROR"
指定该错误无法由上述类型表示。
PinRequestType
扩展程序使用 requestPin 函数请求的代码类型。
枚举
“PIN”
指定请求的代码是 PIN 码。
“PUK”
指定请求的代码是 PUK 码。
PinResponseDetails
属性
-
userInput
字符串(选填)
用户提供的代码。如果用户关闭了对话框或发生了其他错误,则为空。
ReportSignatureDetails
属性
-
错误
"GENERAL_ERROR"
可选生成签名时发生的错误(如果有)。
-
signRequestId
数值
通过
onSignatureRequested
事件收到的请求标识符。 -
签名
ArrayBuffer(可选)
签名(如果成功生成)。
RequestPinDetails
属性
-
attemptsLeft
number 可选
剩余的尝试次数。这样做是为了让任何界面都可以向用户显示此信息。Chrome 不应强制执行此限制,而是应在超过固定请求数量时,由扩展程序调用 stopPinRequest,并将 errorType 设为 MAX_ATTEMPTS_EXCEEDED。
-
errorType
向用户显示的错误模板。如果上一个请求失败,应设置此值,以向用户通知失败原因。
-
requestType
请求的验证码类型。默认值为 PIN 码。
-
signRequestId
数值
Chrome 在 SignRequest 中提供的 ID。
SetCertificatesDetails
属性
-
certificatesRequestId
number 可选
在响应
onCertificatesUpdateRequested
时调用时,应包含收到的certificatesRequestId
值。否则,应取消设置。 -
clientCertificates
当前可用的客户端证书列表。
-
错误
"GENERAL_ERROR"
可选提取证书时发生的错误(如果有)。系统会在适当情况下向用户显示此错误。
SignatureRequest
属性
-
算法
要使用的签名算法。
-
证书
ArrayBuffer
X.509 证书的 DER 编码。扩展程序必须使用关联的私钥对
input
进行签名。 -
输入
ArrayBuffer
要签名的数据。请注意,这些数据未经过哈希处理。
-
signRequestId
数值
要传递给
reportSignature
的请求标识符。
SignRequest
属性
-
证书
ArrayBuffer
X.509 证书的 DER 编码。扩展程序必须使用关联的私钥对
digest
进行签名。 -
摘要
ArrayBuffer
必须签名的摘要。
-
哈希
是指用于创建
digest
的哈希算法。 -
signRequestId
数值
Chrome 57 及更高版本扩展程序需要调用需要此 ID 的方法(例如 requestPin)时,将使用的唯一 ID。
StopPinRequestDetails
属性
-
errorType
错误模板。如果存在,系统会向用户显示该图标。旨在包含停止流程的原因(如果是由错误导致的,例如 MAX_ATTEMPTS_EXCEEDED)。
-
signRequestId
数值
Chrome 在 SignRequest 中提供的 ID。
方法
reportSignature()
chrome.certificateProvider.reportSignature(
details: ReportSignatureDetails,
callback?: function,
)
应作为对 onSignatureRequested
的响应进行调用。
扩展程序最终必须针对每个 onSignatureRequested
事件调用此函数;API 实现会在过了一段时间后停止等待此调用,并在调用此函数时响应超时错误。
参数
-
callback
函数(可选)
callback
参数如下所示:() => void
返回
-
Promise<void>
Chrome 96 及更高版本清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。
requestPin()
chrome.certificateProvider.requestPin(
details: RequestPinDetails,
callback?: function,
)
向用户请求 PIN 码。一次只能有一个正在处理的请求。在其他流程正在进行时发出的请求会被拒绝。如果有其他流程正在进行,扩展程序有责任稍后重试。
参数
-
详细信息
包含有关请求的对话框的详细信息。
-
callback
函数(可选)
callback
参数如下所示:(details?: PinResponseDetails) => void
-
详细信息
-
返回
-
Promise<PinResponseDetails | undefined>
Chrome 96 及更高版本清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。
setCertificates()
chrome.certificateProvider.setCertificates(
details: SetCertificatesDetails,
callback?: function,
)
设置要在浏览器中使用的证书列表。
扩展程序应在初始化后以及当前可用证书集发生每次更改时调用此函数。每次收到此事件时,扩展程序还应调用此函数以响应 onCertificatesUpdateRequested
。
参数
-
要设置的证书。系统会忽略无效证书。
-
callback
函数(可选)
callback
参数如下所示:() => void
返回
-
Promise<void>
Chrome 96 及更高版本清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。
stopPinRequest()
chrome.certificateProvider.stopPinRequest(
details: StopPinRequestDetails,
callback?: function,
)
停止 requestPin
函数启动的固定请求。
参数
-
包含有关停止请求流程的原因的详细信息。
-
callback
函数(可选)
callback
参数如下所示:() => void
返回
-
Promise<void>
Chrome 96 及更高版本清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。
事件
onCertificatesRequested
chrome.certificateProvider.onCertificatesRequested.addListener(
callback: function,
)
请改用 onCertificatesUpdateRequested
。
每当浏览器请求此扩展程序提供的当前证书列表时,此事件就会触发。扩展程序必须使用当前证书列表恰好调用一次 reportCallback
。
参数
-
callback
函数
callback
参数如下所示:(reportCallback: function) => void
-
reportCallback
函数
reportCallback
参数如下所示:(certificates: CertificateInfo[], callback: function) => void
-
certificates
-
callback
函数
callback
参数如下所示:(rejectedCertificates: ArrayBuffer[]) => void
-
rejectedCertificates
ArrayBuffer[]
-
-
-
onCertificatesUpdateRequested
chrome.certificateProvider.onCertificatesUpdateRequested.addListener(
callback: function,
)
如果通过 setCertificates
设置的证书不足,或者浏览器请求更新的信息,系统就会触发此事件。扩展程序必须使用更新后的证书列表和收到的 certificatesRequestId
调用 setCertificates
。
参数
-
callback
函数
callback
参数如下所示:(request: CertificatesUpdateRequest) => void
-
request
-
onSignatureRequested
chrome.certificateProvider.onSignatureRequested.addListener(
callback: function,
)
每当浏览器需要使用此扩展程序通过 setCertificates
提供的证书对消息进行签名时,此事件就会触发。
扩展程序必须使用适当的算法和私钥对 request
中的输入数据进行签名,并使用收到的 signRequestId
调用 reportSignature
将其返回。
参数
-
callback
函数
callback
参数如下所示:(request: SignatureRequest) => void
-
request
-
onSignDigestRequested
chrome.certificateProvider.onSignDigestRequested.addListener(
callback: function,
)
请改用 onSignatureRequested
。
每当浏览器需要使用此扩展程序提供的证书对消息进行签名以响应 onCertificatesRequested
事件时,此事件就会触发。扩展程序必须使用适当的算法和私钥对 request
中的数据进行签名,并通过调用 reportCallback
将其返回。必须只调用一次 reportCallback
。
参数
-
callback
函数
callback
参数如下所示:(request: SignRequest, reportCallback: function) => void
-
request
-
reportCallback
函数
Chrome 47 及更高版本reportCallback
参数如下所示:(signature?: ArrayBuffer) => void
-
签名
ArrayBuffer(可选)
-
-