CertGetCertificateChain 函式 (wincrypt.h)

CertGetCertificateChain 函式會建置從結束憑證開始的憑證鏈結內容,並盡可能回到受信任的 跟證書

語法

BOOL CertGetCertificateChain(
  [in, optional] HCERTCHAINENGINE     hChainEngine,
  [in]           PCCERT_CONTEXT       pCertContext,
  [in, optional] LPFILETIME           pTime,
  [in]           HCERTSTORE           hAdditionalStore,
  [in]           PCERT_CHAIN_PARA     pChainPara,
  [in]           DWORD                dwFlags,
  [in]           LPVOID               pvReserved,
  [out]          PCCERT_CHAIN_CONTEXT *ppChainContext
);

參數

[in, optional] hChainEngine

要使用的鏈結引擎句柄(命名空間和快取)。 如果 hChainEngineNULL,則會使用預設鏈結引擎 HCCE_CURRENT_USER。 這個參數可以設定為 HCCE_LOCAL_MACHINE

[in] pCertContext

結束憑證 CERT_CONTEXT 的指標,這是正在建置鏈結的憑證。 此憑證內容將是第一個簡單鏈結中的零索引元素。

[in, optional] pTime

FILETIME 變數的指標,指出要驗證鏈結的時間。 請注意,時間不會影響信任清單、撤銷或根存放區檢查。 如果 NULL 傳遞至此參數,則會使用目前的系統時間。 信任受信任根目錄的特定憑證是以根存放區目前 狀態 為基礎,而不是此參數傳入的根存放區狀態。 若要撤銷,證書吊銷清單(CRL)本身必須在目前時間有效。 此參數的值是用來判斷CRL中所列的憑證是否已撤銷。

[in] hAdditionalStore

搜尋支援憑證和 憑證信任清單 (CCL) 的任何其他存放區的句柄。 如果未搜尋其他存放區,則可以 NULL 此參數。

[in] pChainPara

包含鏈結建置參數之 CERT_CHAIN_PARA 結構的指標。

[in] dwFlags

指出特殊處理的旗標值。 此參數可以是下列一或多個旗標的組合。

價值 意義
CERT_CHAIN_CACHE_END_CERT
0x00000001
設定此旗標時,會快取結束憑證,這可能會加速鏈結建置程式。 根據預設,不會快取結束憑證,而且每次為其建置鏈結時,都必須加以驗證。
CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY
0x80000000
撤銷檢查只會存取快取的 URL。 這可防止後端或 CA 憑證的網路擷取 CRL 或 OCSP。 CACHE_ONLY 取決於計算機上已從網路擷取CRL或 OCSP的夥伴。
CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT
0x04000000
此旗標會在鏈結建置期間用於 在線憑證狀態通訊協定 (OCSP) 簽署者憑證,以防止迴圈撤銷檢查。 在鏈結建置期間,如果 OCSP 回應是由獨立的 OCSP 簽署者簽署,則除了原始鏈結組建之外,還有針對 OCSP 簽署者憑證本身建置的第二個鏈結。 在第二個鏈結組建期間,會使用此旗標來抑制遞歸的獨立 OCSP 簽署者憑證。 如果簽署者憑證包含 szOID_PKIX_OCSP_NOCHECK 延伸模組,則會略過分葉簽署者憑證的撤銷檢查。 允許 OCSP 和 CRL 檢查。

Windows Server 2003 和 Windows XP: 不支援此值。
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
0x00000004
只會在建置憑證鏈結中使用快取的URL。 因特網和內部網路不會搜尋 URL 型物件,例如 CTL cab、第三方根目錄和 AIA 簽發者。 大部分根應該位於 crypt32.dll 資源中。 如果沒有,則必須進行此擷取,以避免發生鏈結建置錯誤。 這些 cab 和 root 裝載於高效能Microsoft CDN 伺服器上。

注意: 此旗標不適用於撤銷檢查。 將 CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 設定為只使用快取 URL 進行撤銷檢查。 通常,CTL 計程車已經透過 cryptsvc 服務預先擷取。
CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING0x00000040 基於效能考慮,鏈結建置的第二個階段只會考慮品質大於或等於第一次通過期間決定的最高質量的潛在鏈結路徑。 第一個階段只會考慮有效的簽章、完整鏈結和受信任的根目錄,以計算鏈結品質。 此旗標可以設定為停用此優化,並在第二次傳遞期間考慮所有潛在的鏈結路徑。
CERT_CHAIN_DISABLE_MY_PEER_TRUST
0x00000800
不支援此旗標。 「我的」存放區中的憑證永遠不會被視為對等信任。
CERT_CHAIN_ENABLE_PEER_TRUST
0x00000400
“TrustedPeople” 存放區中的結束實體憑證會受到信任,而不需要執行任何鏈結建置。 此函式不會設定 ppChainContext 參數 成員位 CERT_TRUST_IS_PARTIAL_CHAINCERT_TRUST_IS_UNTRUSTED_ROOTdwErrorStatus。

Windows Server 2003 和 Windows XP: 不支援此旗標。
CERT_CHAIN_OPT_IN_WEAK_SIGNATURE
0x00010000
設定此旗標表示呼叫端想要加入加入弱式簽章檢查。

從 Windows 7 和 Windows Server 2008 R2 開始,每個 OS 的匯總更新中都可以使用此旗標。
CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS
0x00000080
預設值只會傳回最高質量的鏈結路徑。 設定此旗標會傳回品質較低的鏈結。 這些會在鏈結內容的 cLowerQualityChainContextrgpLowerQualityChainContext 字段中傳回。
CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE
0x00000100
設定此旗標會禁止從 Windows Update Web Server 自動更新第三方根目錄。
CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT
0x08000000
當您設定 CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT,同時指定 dwUrlRetrievalTimeout 成員 CERT_CHAIN_PARA 結構成員的值時,您在 dwUrlRetrievalTimeout 中指定的值 代表所有撤銷 URL 擷取的累計逾時。

如果您設定 CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 但未指定 dwUrlRetrievalTimeout 值,則預設會將累計逾時上限設定為 20 秒。 每個經過測試的 URL 都會在剩餘累計餘額的一半之後逾時。 也就是說,第一個 URL 會在 10 秒後逾時,第二個在 5 秒後,第三個在 2.5 秒之後等,直到 URL 成功,20 秒才通過,或沒有更多 URL 要測試。

如果您未設定 CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT,鏈結中的每個撤銷 URL 都會指派等於 dwUrlRetrievalTimeout 中所指定值的最大逾時,。 如果您未指定 dwUrlRetrievalTimeout 成員的值,則會為每個撤銷 URL 指派 15 秒的預設逾時上限。 如果沒有 URL 成功,累計逾時值上限為 15 秒,乘以鏈結中的 URL 數目。

您可以使用群組策略來設定預設值。
CERT_CHAIN_TIMESTAMP_TIME
0x00000200
設定此旗標時,pTime 作為時間戳時間,以判斷結束憑證是否有效。 目前時間也可以用來判斷結束憑證是否維持有效時間。 鏈結中所有其他 證書頒發機構單位 (CA) 和跟證書都會使用目前時間進行檢查,而不是 pTime
CERT_CHAIN_DISABLE_AIA
0x00002000
設定此旗標會明確關閉授權單位資訊存取 (AIA) 擷取。 有時候 TLS 伺服器設定不正確,且不會在交握中包含正確的 CA 憑證。

您也可以設定下列撤銷旗標,但一次只能設定此群組中的一個旗標。

價值 意義
CERT_CHAIN_REVOCATION_CHECK_END_CERT
0x10000000
撤銷檢查是在結束憑證上完成,而只會進行結束憑證。
CERT_CHAIN_REVOCATION_CHECK_CHAIN
0x20000000
撤銷檢查會在每個鏈結中的所有憑證上完成。
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
0x40000000
撤銷檢查會在所有鏈結中的所有憑證上完成,但跟證書除外。

[in] pvReserved

這個參數是保留的,而且必須 NULL

[out] ppChainContext

所建立鏈結內容的指標位址。 當您完成鏈結內容時,請呼叫 CertFreeCertificateChain 函式來釋放鏈結。

傳回值

如果函式成功,函式會傳回非零 (TRUE)。

如果函式失敗,則會傳回零 (FALSE)。 如需擴充錯誤資訊,請呼叫 getLastError

言論

當應用程式要求憑證鏈結時,傳回的結構會以 CERT_CHAIN_CONTEXT的形式呈現。 此內容包含一個 CERT_SIMPLE_CHAIN 結構的陣列,其中每個簡單鏈結都會從結束憑證移至自我簽署憑證。 鏈結內容會透過信任清單連接簡單的鏈結。 每個簡單鏈結都包含憑證鏈結、鏈結的摘要信任資訊,以及鏈結中每個憑證元素的信任資訊。

下列備註適用於強式簽章檢查:

  • 您可以藉由設定 pStrongSignParapChainPara 參數所指向之 CERT_CHAIN_PARA 結構的成員,來啟用此函式的強式簽章檢查。
  • 如果在鏈結中找到沒有強簽章的憑證,則會在 CERT_TRUST_STATUS 結構的 dwErrorStatus 字段中設定 CERT_TRUST_HAS_WEAK_SIGNATURECERT_TRUST_IS_NOT_SIGNATURE_VALID 錯誤。 ppChainContext 參數指向 CERT_CHAIN_CONTEXT 結構,接著指向 CERT_TRUST_STATUS 結構。
  • 如果鏈結為強式簽署,則會檢查結束憑證中的公鑰,以判斷它是否符合強式簽章的最低公鑰長度需求。 如果不符合條件,則會在 CERT_TRUST_STATUS 結構的 dwErrorStatus 欄位中設定 CERT_TRUST_HAS_WEAK_SIGNATURECERT_TRUST_IS_NOT_SIGNATURE_VALID 錯誤。 若要停用檢查金鑰長度,請在 dwStrongSignFlagspChainPara 參數所指向之 CERT_CHAIN_PARA 結構的成員中設定 CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG 值。
  • 如果 CERT_STRONG_SIGN_ENABLE_CRL_CHECKCERT_STRONG_SIGN_ENABLE_OCSP_CHECK 旗標是在 CERT_STRONG_SIGN_SERIALIZED_INFO 結構中設定,且找不到沒有強簽章的 CRL 或 OCSP 回應,CRL 或 OCSP 回應就會被視為脫機。 也就是說,CERT_TRUST_STATUS 結構的 dwErrorStatus 欄位中會設定 CERT_TRUST_IS_OFFLINE_REVOCATIONCERT_TRUST_REVOCATION_STATUS_UNKNOWN 錯誤。 此外,dwRevocationResultCERT_REVOCATION_INFO 結構的成員會設定為 NTE_BAD_ALGID

下列建議適用於呼叫這些 API 的任何 Windows 應用程式,以驗證 TLS 伺服器驗證憑證:

  • 只啟用結束憑證的撤銷檢查。
    • 設定 CERT_CHAIN_REVOCATION_CHECK_END_CERT 旗標。
    • 大部分的 CA 憑證都有 CRL 的時間有效期為 1 到 6 個月。
      • 由於已下載的 CRL 已快取,因此這個有效性太長,沒有太多值。
    • 如果 CA 遭到入侵,則憑證也會新增至 Windows 不允許的 CTL
    • TLS 伺服器的建議做法是支援 OCSP 裝訂結束憑證。
      • 在此情況下,除非訂用 OCSP 回應已過期,否則不需要進行網路擷取。
  • 啟用CRL、OCSP、AIA簽發者和 Windows 平臺 CTL cab 和第三方根的網路擷取。
    • 設定上述 CERT_CHAIN_REVOCATION_CHECK_END_CERT 時,這是預設值。
    • 請勿設定下列任何旗標,以防止網路擷取。 如需這些旗標的詳細資訊,請參閱上述 dwFlags 表格:
      • CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL
      • CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY
      • CERT_CHAIN_DISABLE_AIA
  • 啟用CRL和 OCSP 網路擷取的累積逾時。
    • 設定傳遞至 CertGetCertificateChainCERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 旗標。
    • 提供CRL和 OCSP 網路擷取所允許的總時間上限。
  • 將每個網路擷取所允許的時間上限從15縮短為10秒。
    • 將傳遞至 CertGetCertificateChain 到 10 * 1000 毫秒 CERT_CHAIN_PARA 中的 dwUrlRetrievalTimeout 字段設定為 10 * 1000 毫秒。
    • 這也會將累積逾時從 20 秒減少到 10 秒。
      • 只有 OCSP 回應應該下載以取得結束憑證。 5 秒應該足以下載該下載。
  • 忽略離線撤銷錯誤。
  • 快取結束憑證驗證資訊。
    • 設定 CERT_CHAIN_CACHE_END_CERT
      • 除了中繼憑證之外,還能夠對結束憑證的信息進行 LRU 快取。
    • 與同一部伺服器建立多個 TLS 連線很常見。

例子

如需使用此函式的範例,請參閱 範例 C 程式:建立憑證鏈結

要求

要求 價值
最低支援的用戶端 Windows XP [傳統型應用程式 |UWP 應用程式]
支援的最低伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平臺 窗戶
標頭 wincrypt.h
連結庫 Crypt32.lib
DLL Crypt32.dll

另請參閱

CERT_CHAIN_PARA

CertDuplicateCertificateChain

CertFreeCertificateChain

憑證鏈結驗證函式