Question

We recently tried out digitally signing our .NET binaries. We have a Windows Service which typically starts up within 10 seconds. However after we started digitally signing it, the time increased to around 20-30 seconds.

Googling led to me this: http://support.microsoft.com/kb/936707 which basically says that I have to set generatePublisherEvidence to false.

But the description of generatePublisherEvidence on MSDN points to the fact that this is not applicable for .NET 4. Still I tried out this setting and it did work. I double checked that my binaries do target .NET 4.

Can someone please explain me this behavior?

Was it helpful?

Solution 2

I followed the steps mentioned in http://support.microsoft.com/kb/936707 which basically says that I have to set generatePublisherEvidence to false in my application's App.Config.

Edit: As per ssdi's answer, the root cause of the delay is because:

This problem occurs because the application must download the Certificate Revocation List (CRL) for authentication. However, a lack of network connectivity causes the download to fail by timing out. For example, a firewall may potentially block the download. When Windows first starts, the network connection is not yet initialized.

See also article: http://support.microsoft.com/kb/941990 for more details.

OTHER TIPS

I was in a similar situation: An authenticode-signed application on a server without internet access had an unexplained significant startup delay. Setting the generatePublisherEvidence to false seemed to solve the issue, but I was unable to a definitive explanation of why this was necessary.

Microsoft's documentation of the generatePublisherEvidence-element confused me with these two notes:

In the .NET Framework 4 and later, this element has no effect on assembly load times.

and

We recommend that services use the element to improve startup performance. Using this element can also help avoid delays that can cause a time-out and the cancellation of the service startup.

After a lengthy investigation, using Process Monitor, Certutil and debugging into .NET Framework source code, my conclusion is:

The generatePublisherEvidence element is definetely still relevant for .NET 4, even 4.7 which I was using! It is just no longer the case that without it the signature is always verified by the runtime as part of the assembly loading process, but the signature verification might still be triggered (unintentionally) at some point!

Read on for more details.


.NET 2 and 3.5

A digital signature would always be verified when an assembly was loaded, as part of the initialization of the so-called evidence objects used by the Code Access Security (CAS) mechanism. The publisher evidence, which is the one created from the digital signature, was by default not used in CAS, so most of the times this was just a waste of time. And as explained here:

Authenticode verification adds to the startup time. Authenticode-signed assemblies have to be verified with the certification authority (CA). This verification can be time consuming, because it can require connecting to the network several times to download current certificate revocation lists. It also makes sure that there is a full chain of valid certificates on the path to a trusted root. This can translate to several seconds of delay while the assembly is being loaded.

Consider installing the CA certificate on the client computer, or avoid using Authenticode when it is possible. If you know that your application does not need the publisher evidence, you do not have to pay the cost of signature verification.

Starting in .NET Framework 3.5, there is a configuration option that allows the Authenticode verification to be bypassed. To do this, add the following setting to the app.exe.config file:

<configuration>
  <runtime>
    <generatePublisherEvidence enabled="false"/>
  </runtime>
</configuration>

.NET 4

The initialization of evidence objects are now delayed until actually needed, to avoid the startup penalty this lead to in previous versions. This means digital signatures are no longer always verified during assembly loading process. But it turns out there are cases where all evidence objects are being initialized, including the rarely used publisher evidence!

In my case I had an application which was using the Oracle.ManagedDataAccess library to query a database on startup. This library relies on a specific configuration section ("oracle.manageddataaccess.client") in the application configuration. For some reason I did not include such a configuration in my app.config file (nor in my machine.config).

When asked for this configuration section, the System.Configuration assembly, responsible for accessing the configurations, will first look in the machine.config, and then in the application config. When it does not find the requested section in either of these it looks for user-specific configuration files, located in a subfolder path of %AppData%. The full path to these files includes the strong name of the assembly, so therefore the strong name evidence must be created.

The System.Configuration assembly then decides that all evidence objects must be initialized.

Since my application was digitally signed this included initializing the publisher evidence, which means verifying the signature, with CRL checks and all that comes with it. The publisher evidence is not actually used, only the strong name evidence is part of the path to the user configuration files, so again this is just a waste of time.

Adding the "oracle.manageddataaccess.client" section to my app.config file avoided this, the complete set of evidence objects did not have to be initialized, and the digital signature would no longer verified. The startup delay was gone.

In general, setting the generatePublisherEvidence element to false makes sure the publisher evidence is not included whenever the framework decides that the evidence objects must be initialized!

The problem most likely is caused by OCSP and CRL checks being performed for the certificate used for signing. This can increase time significantly. Unfortunately we found no way to disable those checks (and anyway such disabling leads to potential security problems) so we simply don't sign the assemblies with Authenticode but simply strong-name them.

See also article: http://support.microsoft.com/kb/941990

This problem occurs because the application must download the Certificate Revocation List (CRL) for authentication. However, a lack of network connectivity causes the download to fail by timing out. For example, a firewall may potentially block the download. When Windows first starts, the network connection is not yet initialized.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top