C# 如何续订过期的 ClickOnce 证书?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/280472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 21:24:19  来源:igfitidea点击:

How can I renew my expired ClickOnce certificate?

c#visual-studiovisual-studio-2008clickonce

提问by HAdes

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.

我需要对我一年多没有接触过的 ClickOnce 应用程序进行一些更改,因此证书已过期。

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.

因此,我认为我需要使用相同的证书,但不确定如何续订。

采纳答案by Andy Blackman

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 !

Cliff Stanford 已经清理了 Microsoft 的“解决方法”,并将其作为简单的命令行 exe 提供 - 可在此处获得:http: //may.be/renewcert/- Cliff 干得好!

回答by gillonba

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.

我认为这些版本之间的自动更新中断了,但没有持久损坏。我的应用程序仅供内部使用可能有所帮助,因此我不需要正确签名的证书。

回答by gillonba

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.

基本上,您必须构建一个应用程序来延长证书的有效期。上面的链接将使您获得该应用程序的 C++ 源代码。如果你很幸运并且只是自己签名,它可能会起作用。如果您使用 Verisign 等对其进行签名,那么您就是 SOL。您需要卸载并重新安装每个应用程序。这就像你买了一辆新车,发动机坏了,制造商给你一本关于重建发动机的书,而不是更换或修理它。ClickOnce 不是。

回答by RobinDotNet

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.aspxThis covers all cases.

这是关于证书过期的权威 MSDN 文章,其中还包含一个指向 RenewCert 更新的链接。http://msdn.microsoft.com/en-us/library/ff369721.aspx这涵盖了所有情况。

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.

如果您的目标是 .NET 3.5,使用自动更新,并且没有 VSTO 应用程序,或者您的目标是 .NET 4,则更改证书不会给您带来任何问题。

回答by Sogger

Update: @OceanAirdrop did all the work below and made it available on github: https://github.com/OceanAirdrop/ExtendClickOnceCertificate, he has usage instructions on the readme landing page.

更新:@OceanAirdrop 完成了以下所有工作,并在 github 上提供:https: //github.com/OceanAirdrop/ExtendClickOnceCertificate,他在自述登陆页面上有使用说明。



Original Details:

原始细节:

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:

正如@Andy Blackman 所说,更新 pfx 是一种方法,但是当我尝试使用它时,renewcert 在现代 Windows 上运行时出现问题。为了修复 may.be/renewcert 依赖关系,另一个人用 C# 重写了它,这样你就可以在现代 Visual Studio 上使用它:

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

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:

如果您在 wcslen 的 CertNameToStr 中的编组中收到“system.accessviolationexception”,则进行以下更改,以便编组不会爆炸:

  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('
     [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);
    
    ', 1024); + char[] buffer = new char[1024]; + //string buffer = new string('
    -                //var buffer = new char[1024];
    -                string buffer = new string('
    "[path-to-renew-cert-proj-dir\bin\Debug\]renewCert.exe" [old-cert-path\]old_cert_name.pfx [new-cert-path\]new_cert_name.pfx
    
    ', 1024); + char[] buffer = new char[1024]; + //string buffer = new string('##代码##', 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)
    ', 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
  1. 在 Crypt.cs:Line 130 中,将 psz 变量更改为使用 char[] 而不是 string:

    ##代码##
  2. 在 Program.cs:Line 131 中使用字符缓冲区而不是字符串:

    ##代码##
  3. 重建

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

要运行它以快速更新默认五年的证书,请使用如下命令:

##代码##