chrome.certificateProvider

说明

使用此 API 将证书公开给平台,平台可以使用这些证书进行 TLS 身份验证。

权限

certificateProvider

可用性

Chrome 46 及更高版本 仅限 ChromeOS

概念和用法

如需使用此 API 向 ChromeOS 公开客户端证书,通常需要按以下步骤操作:

  • 该扩展程序会注册 onCertificatesUpdateRequestedonSignatureRequested 事件。
  • 扩展程序会调用 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

Chrome 86 及更高版本

支持的加密签名算法类型。

枚举

"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

Chrome 86 及更高版本

属性

  • certificatesRequestId

    数值

    要传递给 setCertificates 的请求标识符。

ClientCertificateInfo

Chrome 86 及更高版本

属性

  • certificateChain

    ArrayBuffer[]

    该数组必须将 X.509 客户端证书的 DER 编码作为其第一个元素。

    此字段必须只包含一个证书。

  • supportedAlgorithms

    此证书支持的所有算法。系统只会使用其中一种算法要求扩展程序提供签名。

Error

Chrome 86 及更高版本

扩展程序可以报告的错误类型。

"GENERAL_ERROR"

Hash

已弃用。已被 Algorithm 替代。

枚举

“MD5_SHA1”
指定 MD5 和 SHA1 哈希算法。

“SHA1”
指定 SHA1 哈希算法。

“SHA256”
指定 SHA256 哈希算法。

“SHA384”
指定 SHA384 哈希算法。

“SHA512”
指定 SHA512 哈希算法。

PinRequestErrorType

Chrome 57 及更高版本

可通过 requestPin 函数向用户显示的错误类型。

枚举

“INVALID_PIN”
指定 PIN 码无效。

“INVALID_PUK”
指定 PUK 无效。

"MAX_ATTEMPTS_EXCEEDED"
指定尝试次数已超出上限。

"UNKNOWN_ERROR"
指定该错误无法由上述类型表示。

PinRequestType

Chrome 57 及更高版本

扩展程序使用 requestPin 函数请求的代码类型。

枚举

“PIN”
指定请求的代码是 PIN 码。

“PUK”
指定请求的代码是 PUK 码。

PinResponseDetails

Chrome 57 及更高版本

属性

  • userInput

    字符串(选填)

    用户提供的代码。如果用户关闭了对话框或发生了其他错误,则为空。

ReportSignatureDetails

Chrome 86 及更高版本

属性

  • 错误

    "GENERAL_ERROR"
     可选

    生成签名时发生的错误(如果有)。

  • signRequestId

    数值

    通过 onSignatureRequested 事件收到的请求标识符。

  • 签名

    ArrayBuffer(可选)

    签名(如果成功生成)。

RequestPinDetails

Chrome 57 及更高版本

属性

  • attemptsLeft

    number 可选

    剩余的尝试次数。这样做是为了让任何界面都可以向用户显示此信息。Chrome 不应强制执行此限制,而是应在超过固定请求数量时,由扩展程序调用 stopPinRequest,并将 errorType 设为 MAX_ATTEMPTS_EXCEEDED。

  • errorType

    向用户显示的错误模板。如果上一个请求失败,应设置此值,以向用户通知失败原因。

  • requestType

    请求的验证码类型。默认值为 PIN 码。

  • signRequestId

    数值

    Chrome 在 SignRequest 中提供的 ID。

SetCertificatesDetails

Chrome 86 及更高版本

属性

  • certificatesRequestId

    number 可选

    在响应 onCertificatesUpdateRequested 时调用时,应包含收到的 certificatesRequestId 值。否则,应取消设置。

  • clientCertificates

    当前可用的客户端证书列表。

  • 错误

    "GENERAL_ERROR"
     可选

    提取证书时发生的错误(如果有)。系统会在适当情况下向用户显示此错误。

SignatureRequest

Chrome 86 及更高版本

属性

  • 算法

    要使用的签名算法。

  • 证书

    ArrayBuffer

    X.509 证书的 DER 编码。扩展程序必须使用关联的私钥对 input 进行签名。

  • 输入

    ArrayBuffer

    要签名的数据。请注意,这些数据未经过哈希处理。

  • signRequestId

    数值

    要传递给 reportSignature 的请求标识符。

SignRequest

属性

  • 证书

    ArrayBuffer

    X.509 证书的 DER 编码。扩展程序必须使用关联的私钥对 digest 进行签名。

  • 摘要

    ArrayBuffer

    必须签名的摘要。

  • 哈希

    是指用于创建 digest 的哈希算法。

  • signRequestId

    数值

    Chrome 57 及更高版本

    扩展程序需要调用需要此 ID 的方法(例如 requestPin)时,将使用的唯一 ID。

StopPinRequestDetails

Chrome 57 及更高版本

属性

  • errorType

    错误模板。如果存在,系统会向用户显示该图标。旨在包含停止流程的原因(如果是由错误导致的,例如 MAX_ATTEMPTS_EXCEEDED)。

  • signRequestId

    数值

    Chrome 在 SignRequest 中提供的 ID。

方法

reportSignature()

Promise Chrome 86 及更高版本
chrome.certificateProvider.reportSignature(
  details: ReportSignatureDetails,
  callback?: function,
)

应作为对 onSignatureRequested 的响应进行调用。

扩展程序最终必须针对每个 onSignatureRequested 事件调用此函数;API 实现会在过了一段时间后停止等待此调用,并在调用此函数时响应超时错误。

参数

返回

  • Promise<void>

    Chrome 96 及更高版本

    清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

requestPin()

Promise Chrome 57 及更高版本
chrome.certificateProvider.requestPin(
  details: RequestPinDetails,
  callback?: function,
)

向用户请求 PIN 码。一次只能有一个正在处理的请求。在其他流程正在进行时发出的请求会被拒绝。如果有其他流程正在进行,扩展程序有责任稍后重试。

参数

返回

  • Promise<PinResponseDetails | undefined>

    Chrome 96 及更高版本

    清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

setCertificates()

Promise Chrome 86 及更高版本
chrome.certificateProvider.setCertificates(
  details: SetCertificatesDetails,
  callback?: function,
)

设置要在浏览器中使用的证书列表。

扩展程序应在初始化后以及当前可用证书集发生每次更改时调用此函数。每次收到此事件时,扩展程序还应调用此函数以响应 onCertificatesUpdateRequested

参数

  • 详细信息

    要设置的证书。系统会忽略无效证书。

  • callback

    函数(可选)

    callback 参数如下所示:

    () => void

返回

  • Promise<void>

    Chrome 96 及更高版本

    清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

stopPinRequest()

Promise Chrome 57 及更高版本
chrome.certificateProvider.stopPinRequest(
  details: StopPinRequestDetails,
  callback?: function,
)

停止 requestPin 函数启动的固定请求。

参数

  • 详细信息

    包含有关停止请求流程的原因的详细信息。

  • callback

    函数(可选)

    callback 参数如下所示:

    () => void

返回

  • Promise<void>

    Chrome 96 及更高版本

    清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

事件

onCertificatesRequested

Chrome 47 及更高版本 不超过 MV2 从 Chrome 86 开始已废弃
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 86 及更高版本
chrome.certificateProvider.onCertificatesUpdateRequested.addListener(
  callback: function,
)

如果通过 setCertificates 设置的证书不足,或者浏览器请求更新的信息,系统就会触发此事件。扩展程序必须使用更新后的证书列表和收到的 certificatesRequestId 调用 setCertificates

参数

onSignatureRequested

Chrome 86 及更高版本
chrome.certificateProvider.onSignatureRequested.addListener(
  callback: function,
)

每当浏览器需要使用此扩展程序通过 setCertificates 提供的证书对消息进行签名时,此事件就会触发。

扩展程序必须使用适当的算法和私钥对 request 中的输入数据进行签名,并使用收到的 signRequestId 调用 reportSignature 将其返回。

参数

onSignDigestRequested

小于等于 MV2 从 Chrome 86 开始已废弃
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(可选)