How can I renew my expired ClickOnce certificate?

2019-01-18 02:29发布

问题:

I need to make some changes to a ClickOnce application that I haven't touched for over a year and therefore the certificate has expired.

I've read that publishing with a new certificate will make the application fail, because it will be signed with a different key.

Therefore I think I need to use the same certificate but not sure how to renew it.

回答1:

If you're after a quick solution, then you can "renew" your existing certificate and just give it a longer expiry date.

Cliff Stanford has cleaned up the Microsoft "workaround" and made it available as a simple command line exe - available here: http://may.be/renewcert/ - Nice work Cliff !



回答2:

Here's the definitive MSDN article on certificate expiration, which also includes a link to an update on RenewCert. http://msdn.microsoft.com/en-us/library/ff369721.aspx This covers all cases.

If you are targeting .NET 3.5, using automatic updates, and don't have a VSTO app, OR you are targeting .NET 4, changing the certificate will not cause you any problems.



回答3:

Basically you have to build an app to extend the expiry of your certificate. The links above will get you to the C++ source code for the app. If you are lucky and just signed it yourself it may work. If you used Verisign etc. to sign it you are SOL. You will need to uninstall and re-install every app. It's like you buy a new car the engine blows and the manufacturer gives you a book on re-building engines instead of replacing or fixing it. ClickOnce is not.



回答4:

If I remember correctly, I ran into the same problem and just created a new certificate.

I think the automatic update broke between those versions, but there was no lasting damage. It might have helped that my application was for internal use only, so I didn't need a properly signed certificate.



回答5:

Renewing the pfx is the way to go as @Andy Blackman states, but renewcert has issues running on modern windows when I tried to use it. To fix the may.be/renewcert dependencies another guy rewrote it in C# so you can use it on modern Visual Studio:

https://nathanpjones.com/2013/01/renewing-temporary-certificate/

Download the source from his website, compile, and run.


If you get a "system.accessviolationexception" on the marshalling in CertNameToStr for wcslen, then make the following changes so the marshalling doesn't blow up:

  1. In Crypt.cs:Line 130 change the psz variable to use char[] instead of string:

     [DllImport("crypt32.dll", CharSet = CharSet.Auto)]
    -        internal static extern int CertNameToStr(X509Encoding dwCertEncodingType, ref CRYPT_DATA_BLOB pName, CertNameType dwStrType, ref string psz, int csz);
    +        internal static extern int CertNameToStr(X509Encoding dwCertEncodingType, ref CRYPT_DATA_BLOB pName, CertNameType dwStrType, [In, Out] char[] psz, int csz);
    
  2. In Program.cs:Line 131 use a char buffer instead of a string:

    -                //var buffer = new char[1024];
    -                string buffer = new string('\0', 1024);
    +                char[] buffer = new char[1024];
    +                //string buffer = new string('\0', 1024);
                     int d;
    -                if ((d = Crypt.CertNameToStr(Crypt.X509Encoding.ASN_Encodings, ref certNameBlob, Crypt.CertNameType.CERT_X500_NAME_STR, ref buffer, 1024 * sizeof(char))) != 0)
    +                if ((d = Crypt.CertNameToStr(Crypt.X509Encoding.ASN_Encodings, ref certNameBlob, Crypt.CertNameType.CERT_X500_NAME_STR, buffer, 1024 * sizeof(char))) != 0)
    
  3. rebuild

To run it to just quickly renew cert for default five years, use a cmd like:

"[path-to-renew-cert-proj-dir\bin\Debug\]renewCert.exe" [old-cert-path\]old_cert_name.pfx [new-cert-path\]new_cert_name.pfx