这是一个奇怪的问题,但我会尝试。
我使用目标框架作为4.5.2启动了我的项目,并且要求使用SHA1算法签署XML文件。我在这个MSDN页面中使用了这个例子,它运行良好:
SignedXml.CheckSignature Method(X509Certificate2,Boolean) - > 示例部分
https://msdn.microsoft.com/en-us/library/ms148731(v=vs.110).aspx#Anchor_3
之后,要求改为SHA256算法。我使用这些页面中的代码来调整原始代码,并且工作正常,到那时我使用4.6作为目标框架:
将SHA256与SignedXml类一起使用
https://blogs.msdn.microsoft.com/winsdk/2015/11/14/using-sha256-with-the-signedxml-class/.net Framework 4.6.2增加了对使用RSA-SHA256签名XML文档的支持 https://www.stum.de/2016/05/19/net-framework-4-6-2-adds-support-to-sign-xml-documents-using-rsa-sha256/
然后我发现框架的4.6.2版本增加了对SHA256的完全支持,并且不再需要CryptoConfig.AddAlgorithm()调用。我将项目更改为版本4.6.2,进行了所需的更改,对CryptoConfig.AddAlgorithm()调用进行了评论,它运行得很好。
但是现在我们还有另一个需求变化:我们希望我们的软件能够在Windows XP下运行(是的,我们确实让用户仍在使用它),最后一个与XP(SP3)一起使用的框架版本是v4.0。因此,我需要测试使用SHA256签署XML文件是否可以在框架4.0中工作。
然后我将目标框架更改为v4.0并开始更改。我在CryptoConfig.AddAlgorithm()调用中使用的RSAPKCS1SHA256SignatureDescription类仅在框架4.5之后才可用,所以我必须编写自己的版本,就像我在一些网页中看到的那样。
但是,现在奇怪的是。我保持CryptoConfig.AddAlgorithm()调用注释,看看会发生什么,所以我可以写自定义类,但是,它只是工作!我认为CryptoConfig.AddAlgorithm()已在项目或我的机器的某处注册了算法。我对此进行了研究,但一无所获。所以我尝试了另一台机器,它也有效,但该机器之前可能已执行过前面的代码,因此也可以注册算法。我尝试了另一台机器,我不确定,但也在那里工作。
所以,我去了一个从未见过这个项目的机器,那时我编译并部署了可执行文件(我正在其他机器上执行VS项目)。我在该机器上删除了4.0之后的所有.NET框架并尝试运行该应用程序。并且......它仍然有效!它使用SHA256签署XML,并且工作正常。所有这些机器都运行Windows 10。
有人知道发生了什么事吗?
答案 0 :(得分:1)
您定位的版本和您正在运行的版本不同。任何目标4.0-4.7都在4.7运行时运行。由于添加支持是非破坏性的,因此没有使用目标版本退出。
由于WinXP不具备4.6.2,您需要自己添加处理程序。针对XP所具有的任何框架将限制您使用可用的API,尽管您已经看到运行时可能表现不同,因此您应该在目标操作系统上进行测试。
答案 1 :(得分:0)
在 Marteen Bodewes 评论和 bartonjs 回答之后,我做了一些研究并学习了一些关于.NET Framework的内容。在过去,我真的买了关于.NET的并排功能的微软营销,但我一直认为框架的每个版本都会在同一台机器上共存。今天我已经知道那不完全是那样的。
首先,CLR和框架是不同的东西,不一定走在一起。公共语言运行时(CLR)是框架的关键部分,用于判断是否存在并行共存。到目前为止,CLR只有4个版本:1.0,1.1,2.0和4:
公共语言运行时(CLR) - 公共语言运行时的版本
https://docs.microsoft.com/en-us/dotnet/standard/clr#versions-of-the-common-language-runtime
所有共享相同CLR版本的框架版本将是以前版本的就地替代版本。因此,如果您在计算机上只有Framework 2.0,那么您就拥有了CLR 2.0和Framework 2.0。如果在该计算机上安装Framework 3.5,则仍然具有CLR 2.0,但Framework 2.0将替换为3.5版本。之后,如果安装Framework 4.0,则具有CLR 2.0和CLR 4以及Framework 3.5和Framework 4.0。如果在同一台机器上安装Framework 4.5,您仍然拥有CLR 4,但现在框架4.0已被4.5版取代。
这就是为什么,至少在我的机器上,我在'C:\ Windows \ assembly'路径下只有v2.0和v4.0文件夹。我注意到,在运行时,.NET DLL是从该路径加载的。不过,我不确定'C:\ Windows \ Microsoft.NET \ Framework'的目的是什么。
但这并没有回答我向bartonjs提出的问题:如果新版本的框架消失了以前从该机器共享相同CLR的版本,那么Visual Studio如何知道哪些类,方法,属性等等。对于为项目选择的特定目标框架有效吗?
所以我发现Scott Hanselman的这篇优秀文章:
.NET版本控制和多目标 - .NET 4.5是对.NET 4.0的就地升级 https://www.hanselman.com/blog/NETVersioningAndMultiTargetingNET45IsAnInplaceUpgradeToNET40.aspx
答案是:在目录'C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework \ .NETFramework'下是通过机器的所有版本的存档,Visual Studio使用这些版本! (为什么不把所有这些东西放在一个地方,然后真正并排共存呢?)
在完成所有这些答案后,我更了解发生了什么(顺便说一下,我发现最后一台机器确实安装了框架4.7,因为我已经卸载了所有,但我打算在其上安装Visual Studio Community 2017 ,并取消了我的测试,但是,Visual Studio安装程序已经安装,并且可能将最后一个框架放在机器上),当我在Windows XP SP3下执行应用程序时真的失败并不奇怪。但现在我知道该怎么做。