託管 Windows 服務在數字簽名後啟動緩慢
我們最近嘗試對我們的 .NET 二進製文件進行數字簽名。我們有一個通常在 10 秒內啟動的 Windows 服務。然而,在我們開始對其進行數字簽名後,時間增加到了 20-30 秒左右。
Google搜尋導致我:http: //support.microsoft.com/kb/936707這基本上說我必須將 generatePublisherEvidence 設置為 false。
但是MSDN上 generatePublisherEvidence 的描述指出這不適用於 .NET 4。我仍然嘗試了這個設置並且它確實有效。我仔細檢查了我的二進製文件是否以 .NET 4 為目標。
有人可以解釋一下這種行為嗎?
我按照http://support.microsoft.com/kb/936707中提到的步驟進行操作,基本上說我必須在我的應用程序的 App.Config中將generatePublisherEvidence設置為false 。
**編輯:**根據 ssdi 的回答,延遲的根本原因是:
出現此問題的原因是應用程序必須下載證書吊銷列表 (CRL) 進行身份驗證。但是,缺少網路連接會導致下載因超時而失敗。例如,防火牆可能會阻止下載。Windows 首次啟動時,網路連接尚未初始化。
另請參閱文章: http: //support.microsoft.com/kb/941990了解更多詳細資訊。
我也遇到過類似的情況:在無法訪問 Internet 的伺服器上,一個經過驗證碼簽名的應用程序出現無法解釋的顯著啟動延遲。將generatePublisherEvidence設置為 false 似乎可以解決問題,但我無法明確解釋為什麼這是必要的。
Microsoft 的generatePublisherEvidence-element 文件讓 我對這兩個註釋感到困惑:
在 .NET Framework 4 及更高版本中,此元素對程序集載入時間沒有影響。
和
我們建議服務使用該元素來提高啟動性能。使用此元素還可以幫助避免可能導致超時和取消服務啟動的延遲。
經過長時間的調查,使用Process Monitor, Certutil 並調試到.NET Framework 原始碼,我的結論是:
generatePublisherEvidence 元素絕對仍然與 .NET 4 相關,甚至是我使用的 4.7!不再是沒有它,簽名總是由執行時驗證作為程序集載入過程的一部分,但簽名驗證可能仍會在某個時候(無意地)觸發!
請閱讀以獲得更多詳情。
.NET 2 和 3.5
載入程序集時始終會驗證數字簽名,作為程式碼訪問安全 (CAS) 機制使用的所謂證據對象的初始化的一部分。發布者證據是由數字簽名創建的,預設情況下不會在 CAS 中使用,所以大多數時候這只是浪費時間。正如這裡所解釋的:
Authenticode 驗證增加了啟動時間。Authenticode 簽名的程序集必須通過證書頒發機構 (CA) 進行驗證。此驗證可能很耗時,因為它可能需要多次連接到網路才能下載目前的證書吊銷列表。它還確保在通往受信任根的路徑上有完整的有效證書鏈。在載入程序集時,這可能會導致幾秒鐘的延遲。
考慮在客戶端電腦上安裝 CA 證書,或盡可能避免使用 Authenticode。如果您知道您的應用程序不需要發布者證據,則您無需支付簽名驗證的費用。
從 .NET Framework 3.5 開始,有一個配置選項允許繞過 Authenticode 驗證。為此,請將以下設置添加到 app.exe.config 文件:
<configuration> <runtime> <generatePublisherEvidence enabled="false"/> </runtime> </configuration>.NET 4
證據對象的初始化現在延遲到實際需要,以避免在以前的版本中導致啟動懲罰。這意味著在程序集載入過程中不再總是驗證數字簽名。但事實證明,在某些情況下,所有證據對像都被初始化,包括很少使用的發布者證據!
就我而言,我有一個應用程序使用 Oracle.ManagedDataAccess 庫在啟動時查詢數據庫。此庫依賴於應用程序配置中的特定配置部分(“oracle.manageddataaccess.client”)。出於某種原因,我沒有在我的 app.config 文件(也沒有在我的 machine.config)中包含這樣的配置。
當詢問此配置部分時,負責訪問配置的 System.Configuration 程序集將首先查看 machine.config,然後查看應用程序配置。當它在其中任何一個中都找不到請求的部分時,它會查找位於 %AppData% 子文件夾路徑中的使用者特定配置文件。這些文件的完整路徑包括程序集的強名稱,因此必須創建強名稱證據。
System.Configuration 程序集然後決定必須初始化所有證據對象。
由於我的應用程序是數字簽名的,這包括初始化發布者證據,這意味著驗證簽名,使用 CRL 檢查以及它附帶的所有內容。發布者證據實際上並沒有被使用,只有強名稱證據是使用者配置文件路徑的一部分,所以這只是浪費時間。
將“oracle.manageddataaccess.client”部分添加到我的 app.config 文件中可以避免這種情況,不必初始化完整的證據對象集,並且不再驗證數字簽名。啟動延遲消失了。
通常,將 generatePublisherEvidence 元素設置為 false 可確保在框架決定必須初始化證據對象時不包含發布者證據!