我也遇到过类似的情况:在无法访问 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 可确保在框架决定必须初始化证据对象时不包含发布者证据!