24

At work we had a ClickOnce application that, when the client would try to install, was throwing the exception:

  • Exception reading manifest from file:/FILEPATH: the manifest may not be valid or the file could not be opened.

    Manifest XML signature is not valid.

    SignatureDescription could not be created for the signature algorithm supplied.

To solve this, we ended up using another certificate file, and it worked fine (resigned the manifest).

But we can not understand why it would work to install the application in the developers machines (even developers that were not working with the application), but it would not work for the clients' machines?

We don't have much information on how the certificates were created or the ClickOnce package, because the person that did it is gone and didn't leave documentation about it.

The certificate that was being used didn't have a password and normal users do not have administrator rights.

From Stack Overflow question Manifest XML signature is not valid, I could guess that the problem maybe was that they created the project and certificate with .NET Framework 4.5 and then when they set the application to run with .NET Framework 4.0, they didn't change the signature algorithm. But then I would asume it shouldn't work for the developers either.

Any insight you could give me would be greatly appreciated.

Community
  • 1
  • 1
Dzyann
  • 5,062
  • 11
  • 63
  • 95
  • Silly question, but can the machine that is having the problems open the file using the same path as that specified in the error message? – Josh May 15 '13 at 19:58
  • 1
    Yes, everything was accessible. What's more I just edited the package and used another Certificate, so everything was in the same place than before, but with another certificate. And it worked in the computer that was having problems. – Dzyann May 15 '13 at 20:10

3 Answers3

26

Update: This is fixed as of Visual Studio 2013 Update 3. Try publishing your app from that version of VS or later.

Previous answer:

It's because your developer machine had .NET 4.5 installed, while your client machines only had .NET 4.0 installed. The .NET 4.0 client machines can't read the manifest, as they expect SHA-1, while the .NET 4.5 developer machines can.

See this blog post for some additional context.

This change is due to the fact that we stopped using legacy certificates as default (SHA-1) in NetFX4.5 to sign manifest and instead, use newer version (SHA-256), which is not recognized by NetFx4.0 runtime. Therefore, while parsing the manifest, 4.0 runtime complains of an invalid manifest. For legacy frameworks, when we try to run a ClickOnce app on a box that does not have targeted runtime, ClickOnce pops up a message to user saying “you need xxxx.xx runtime to run this app”. But starting .NET 4.5, if a 4.5 ClickOnce app is run on the box with only .NET 4.0 installed, the message complains about an invalid manifest. In order to resolve the issue, you must install .Net Framework 4.5 on the target system.

Try signing your manifest with a SHA-1 certificate instead of a SHA-2 certificate.

Matthew King
  • 5,114
  • 4
  • 36
  • 50
  • 7
    +1 but damn MS, what if you can't install 4.5 because it's a 2k3 server? What is the point of being able to target earlier versions of the runtime if you can't then install them? – Richard Benson Jun 07 '13 at 16:41
  • Yes, it seems strange to me, too. From my understanding, you'll have to just use a SHA-1 certificate. – Matthew King Jun 09 '13 at 11:00
  • 4
    In case you want to add instructions to your answer, the solution is to open your project in VS2010, go to project properties and select signing, then "create test certificate". This will generate one with SHA1 and doesn't seem to change anything else in the project. – Richard Benson Jun 10 '13 at 15:27
  • @RichardBenson I tried posting your advice to Soumitra's MSDN blog above, but it was flagged as spam :-). Thank you for your actual solution to this problem. – John Vance Nov 22 '13 at 05:38
  • 1
    See my answer below. Starting with Visual Studio 2013 Update 3 RC, the issue has been resolved. – Michael Zlatkovsky - Microsoft Jul 10 '14 at 20:40
  • 1
    That can't be right -- we saw the same issue on machines that had the .NET 4.5 Framework installed -- the certificate was SHA-2, it was Windows 7 -- we downgraded back to SHA-1, and the problem went away. – BrainSlugs83 Jul 28 '14 at 02:25
  • +1, Had this problem which is stated in (`Previous answer` part of this answer). Installing .NET 4.5 on client machine solved the problem. SHA-256 was used to sign the executables/manifests etc. – sameerkn Feb 24 '17 at 10:32
13

We had similar problem - we have a .NET 4.0 application, meant to work on machines with .NET 4.0 or higher. As our code signing certificate expired we purchased a new one and as Sha1 is going to be depricated, we received a Sha256 one. I should say that our build machine has .NET 4.5 installed, so the framework assemblies are all updated on that machine.

We noticed that the following error started to appear only on .NET 4.0 machines once we migrated to the new certificate:

* Activation of http://localhost/publish/Test.application resulted in exception. Following failure messages were detected:
    + Exception reading manifest from http://localhost/publish/Test.application: the manifest may not be valid or the file could not be opened.
    + Manifest XML signature is not valid.
    + SignatureDescription could not be created for the signature algorithm supplied.

After a little research fe found out this thread and some other, suggesting upgrading to .NET 4.5, but this is not working solution for us - we don't want to force our clients to update .NET framework (~20% are still using .NET 4.0). Here are the solutions we came up to:

  • Sign the manifests on a machine that has only .NET 4.0 installed
  • Sign with the following PowerShell script instead of using mage.exe:
function SignFile($filePath, $timeStampUri, $certThumbprint)
{
    #Add-Type System.Security

    $x509Store = New-Object -TypeName ([System.Security.Cryptography.X509Certificates.X509Store]) -ArgumentList ([System.Security.Cryptography.X509Certificates.StoreName]::My),([System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser)
    try
    {
        $x509Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
        $x509Certificate2Collection = $x509Store.Certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $certThumbprint, $false);
        if ($x509Certificate2Collection.Count -eq 1)
        {
            $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]@($x509Certificate2Collection)[0]

            # This will force using of SHA1 instead of SHA256
            $cert.SignatureAlgorithm.FriendlyName = ""

            Add-Type -AssemblyName "Microsoft.Build.Tasks.v4.0"

            [Microsoft.Build.Tasks.Deployment.ManifestUtilities.SecurityUtilities]::SignFile($cert, $timeStampUri, $filePath)
        }
    }
    finally
    {
        $x509Store.Close();
    }
}

EDIT: I actually use this command-let to sign the manifest files: https://gist.github.com/nedyalkov/a563dd4fb04d21cb91dc

Hope this information will save time and effort to somebody!

sasfrog
  • 2,410
  • 1
  • 17
  • 28
Miroslav Nedyalkov
  • 1,101
  • 1
  • 10
  • 22
  • The accepted answer does not suggest to update to 4.5, that is just the quote. The solution was to sign with SHA-1. – Dzyann Jan 14 '14 at 13:34
  • Yes, you are right. I mixed the quote and the answer. Anyway signing with Sha1 is not always an option, as it is suggested to be obsolete this year. This was our case as well - we already had purchased a Sha256 certificate and if we hadn't found this work around, the only option was to purchase a new Sha1 certificate just for this bug. That's why I decided to share it :) – Miroslav Nedyalkov Jan 16 '14 at 14:49
  • So that script allows you sign the assemblies with Sha-256 in a machine with .Net 4.0? – Dzyann Jan 16 '14 at 15:09
  • No, it allows you to sign the manifest with Sha-1 in a machine with .Net 4.5, because the version parameter of mage doesn't seem to work correctly. When we reflected the code of the mage tool, we noticed it assumes that you would like to sign with the algorithm of the certificate and disregards the parameter passed to mage.exe – Miroslav Nedyalkov Jan 22 '14 at 12:38
  • Thank you for that script. You actually saved me a big headache! – PiercingDegree Jun 12 '14 at 14:45
  • Hi @MiroslavNedyalkov, I have arrived at the same point as you, but am unsure about where/how to implement what you've suggested. Can you point me to an appropriate resource or elaborate on how to implement this? Would be very grateful. – sasfrog Sep 11 '14 at 06:42
  • 1
    Hello @sasfrog. I use the code I shared to sign the manifest files after editing them with mage.exe, because signing with mage.exe will sign them with SHA256 hashing algorithm. What I actually use is this command-let - https://gist.github.com/nedyalkov/a563dd4fb04d21cb91dc. – Miroslav Nedyalkov Sep 11 '14 at 08:37
  • Hi again @MiroslavNedyalkov thanks for your help. After a lot of trial and error I have got as far as succeeding with your cmdlet, but when installing I'm getting a "Reference in the deployment does not match the identity defined in the application manifest" error, and I'm stuck there. I'm publishing first with VS's Signing option disabled, then signing each of the .vsto, .manifest and setup.exe with the cmdlet, is that right? Do I need to take further steps? I note you say "after editing them with mage" - what do you need to edit? Is that relevant to this issue? Thanks – sasfrog Sep 21 '14 at 14:08
  • 1
    Hello @sasfrog. I'm using this code as part of continuous delivery procedure where I move the ClickOnce installer from one environment to another one and I need to update the config file and the deployment manifest (the .application file). After this change I need to update the checksum of the application manifest, sign it and update the checksum of the deployment manifest and sign it as well. You may refer to the following articles about how the manifest files should be update - http://bit.ly/1vart0Z and http://bit.ly/1prU2Bk. I use the cmdlet to sign the manifest files after updating them. – Miroslav Nedyalkov Sep 24 '14 at 11:23
  • @MiroslavNedyalkov: [1] Am having an Addin developed using .Net 4.0. On my development m/c am having .Net 4.5 installed. As per your answer should I uninstall .Net 4.5 and then rebuild/publish the Addin. [2] Can you please show how can `SignFile` Function be executed. Giving an example of exact parameters to be passed to the function. [3] Am having certificate file "CompanyName.pfx". Thanks. – sameerkn Feb 01 '17 at 15:09
  • @MiroslavNedyalkov: I am using your cmdlet but I'm unsure about which files should I sign. I started signing the vsto but then I got errors, then we signed the manifest and got different errors, at last we signed the manifest and the vsto as recommended on the link with no success. What should we sign? – Ignacio Soler Garcia Feb 15 '17 at 17:37
  • Guys, I'm really sorry, but this was so long time ago that I don't quite remember what we did there. I think we used to sign the manifest file as this is what WPF requires to be signed, but I'm not sure. I don't have any example of this cmdlet in use as it was used in a project I no longer work on. – Miroslav Nedyalkov Feb 17 '17 at 06:49
0

We also faced similar issue in following scenario.

We simply migrated from vs2008 to vs2013-update 5.

Our clickonce app is on .net 3.5.

After this, our clickonce app build using nant script on command prompt was giving same error "Manifest XML signature is not valid" on a machine which is having .net framework version older than 4.5.

As we were using vs2013-update 5, it was obviously not related to fix done in vs2013-update 3.

After doing trial and error on one sample app, we sorted it out that mage.exe which we are using to resign the manifest after updating manifest. When we create setup using VS2013 developer command prompt, it uses mage.exe which is installed with VS2013 and it is not having the same fix which is done in VS2013 update 3. Using old mage.exe, installed with vs2008 (normally located at "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin") solved our problem.

rikencpatel
  • 53
  • 1
  • 6