Search code examples
clickonceauthenticode

How to Authenticode sign ClickOnce deployment with an EV SHA2 cert and avoid "Unknown Publisher"


When signing my ClickOnce deployment via Visual Studio's project "Signing" settings page I specified our SHA2 (SHA256) EV Authenticode certificate and publish.

enter image description here

After publishing and attempting to run the bootstrapper (setup.exe) I'm presented with the "Unknown Publisher" in the ClickOnce dialog.

enter image description here

The EV certificate in question is valid and running on an eToken hardware token with SafeNet client tools to communicating with the token. Signing regular PE files (exe and dll) with signtool always produces perfectly valid assemblies and the publisher is known. This is only an issue with ClickOnce deployments. In addition, the individual files of the ClickOnce deployment look perfectly valid because the digital signatures tab of the file properties dialog is listed correctly for the bootstrapper (setup.exe) and the assembly files suffixed with ".deploy".

enter image description here

Also, the ".application" and ".manifest" files are appropriately mutated (probably via mage by Visual Studio) to contain the <publisherIdentity> element along with the algorithm set correctly.

enter image description here

The signing machine is running Win10 and I've tried every permutation I could imagine:

  • With and without a timestamp
  • With and without strong name signing
  • With and without online publishing
  • With and without https online publishing
  • With and without specific "Update location" via Publish page
  • With and without "Publisher name" set via Description in Publish page
  • With every combination of Manifest options:
    • Exclude deployment provider URL
    • Block application from being activated via a URL
    • Use application manifest for trust information
  • Multiple machines on various versions of Windows
  • Manual manifest signing and assembly signing via mage and signtool (yes mageui as well)
  • Ensure the cert is not revoked with certificate provider

There appears to be someone else experiencing this.


Solution

  • The reason this occurs is due to a couple of factors:

    1. ClickOnce displays "Unknown Publisher" when using a SHA2 Authenticode certificate.
    2. On January 1st 2016 Windows deprecated SHA1 for Authenticode signing /code signing. Windows SmartScreen technology thus displays "Unknown Publisher" when using a SHA1 Authenticode certificate.

    This is in effect a catch-22, you need SHA1 for ClickOnce publisher verification and SHA2 for SmartScreen. Nice.

    Work with your certificate provider (hopefully a true CA) to get you a SHA1 and SHA2 certificate. The folks at DigiCert were great. You must work with your CA in most cases because even if you already have your own SHA2 cert and you work with them to also get a SHA1 cert (or vica-versa), it will likely auto-revoke any existing certificates you have with them. In the case of DigiCert they were able to prevent the automatic revocation when I explained what I wanted to try (dual signing).

    After you've installed those on your EV token, configure Visual Studio to sign your ClickOnce manifests with your SHA1 certificate. Ideally you'll also supply a Timestamp server in that same dialog for the eventual expiration of your certificate.

    enter image description here

    After publishing your ClickOnce deployment locally and before distributing, dual sign your ClickOnce bootstrapper (setup.exe) by appending your SHA2 certificate.

    signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /as /sha1 YourCertThumbprintHash "X:\Deployment\ClickOnceCert\setup.exe"
    

    Note, one way to find your cert thumbprint is via the Certificates MMC snap-in. And yes, thumbprints are supposed to be SHA1 for SHA2 certs.

    enter image description here

    Now, the bootstapper shows both of your certificates in the Digital Signatures tab of the file properties dialog.

    enter image description here

    When you run the setup.exe from the location specified as your "Installation Folder URL" of your Publish page in Visual Studio, you should see the publisher as trusted. It's important to understand the Installation Folder because if you were to run the app from another location you should expect that not to be trusted because the bootstrapper will make calls to the known Installation Folder to retrieve Application Files.

    enter image description here