2017-07-28 53 views
1

这是一个奇怪的问题,但我会尝试。使用SHA256签名XML时,它不应该工作

我开始使用目标框架作为4.5.2的项目,并且要求使用SHA1算法签署XML文件。我使用的例子在这个MSDN页面,它工作得很好:

之后,要求改为SHA256算法。我使用的代码在这些页面以适应该原代码,它工作得很好,我用的是4.6,通过当时的目标框架:

后来我发现,该框架的4.6.2版本增加了对SHA256全力支持,并且加密Config.AddAlgorithm()调用不再是必需的。我将项目更改为版本4.6.2,进行了所需的更改,评论CryptoConfig.AddAlgorithm()调用,它工作得很好。我们希望我们的软件能够在Windows XP下工作(是的,我们确实有用户仍然在使用它),最后一个与XP(SP3)一起工作的框架版本是v4.0。所以,我需要测试用SHA256签名XML文件是否可以在Framework 4.0中工作。

我将目标框架更改为v4.0,然后开始更改。我在CryptoConfig.AddAlgorithm()调用中使用的RSAPKCS1SHA256SignatureDescription类仅在框架4.5之后才可用,因此我必须编写自己的版本,正如我在某些网页中看到的那样。

但是,现在奇怪的事情。我保留了CryptoConfig.AddAlgorithm()调用的注释,看看会发生什么,所以我可以编写自定义类,但它工作正常!

我以为CryptoConfig.AddAlgorithm()已经在项目或我的机器的某处注册了算法。我研究了这个,但什么都没发现。所以我尝试了另一台机器,它也工作过,但那台机器可能以前执行过以前的代码,所以它可能也注册了算法。我尝试了另一台机器,那个我不确定的机器,但是也在那里工作。所以,我去了一台甚至从未见过该项目的机器,那时我编译了它并部署了可执行文件(我在其他机器上执行了VS项目)。我在该机器上4.0之后删除了所有的.NET框架,并试图运行该应用程序。而且......它仍然有效!它使用SHA256签署XML,并且工作正常。所有这些机器都运行Windows 10.

有人有什么想法是怎么回事?

+0

为了保持兼容性,密码算法常常被移植到旧版本。这可能是一个非常简单的答案。这可能是因为如果你安装Windows XP并且4.0的第一次可分配,它将会失败。请注意,微软有没有保留/显示真正的版本信息(4.0.0和4.0.999的文件可能具有相同的文件名,只是由最后的更改日期区分)。 –

+0

但是真正奇怪的是,当我开始将代码适配到SHA256时,没有CryptoConfig.AddAlgorithm()调用,它就无法工作。我正在使用框架4.6。而现在,与框架4.0它的作品。我会这样做,用干净的Windows XP SP3安装创建一个虚拟机,看看会发生什么。 –

回答

0

您定位的版本和您运行的版本不一样。任何目标4.0-4.7都可以在4.7运行时运行。由于添加支持不会中断,因此目标版本撤销并未完成。

由于WinXP不会有4.6.2,你需要自己添加处理程序。针对XP提供的任何框架将限制您使用的API,但正如您所看到的,运行时可能会有不同的表现,所以您应该在目标操作系统上进行测试。

+0

你的意思是,即使我的目标版本是4.0,而且机器上有4.0版本,但机器上也有版本4.7,它可以在我的项目上运行版本4.7而不是版本4.0?但是,那么为什么在我更改框架版本之后,对X509Certicate2.GetRSAPrivateKey()方法的调用就停止了工作?为什么我的应用程序的编译版本在卸载了4.0以上所有版本的机器上运行?它对我来说依然没有意义! –

+0

有没有办法在运行时检查我的应用程序正在使用哪个版本的框架? –

+0

我会尝试:https://stackoverflow.com/questions/8517159/how-do-i-detect-at-runtime-that-net-version-4-5-is-currently-running-your-code –

0

Marteen Bodewes评论和bartonjs答案,我已经做了一些研究和了解.NET框架的一些事情。在过去,我真的买了微软市场营销的关于.NET的并行功能,但我一直认为,每个版本的框架将在同一台机器上共存。今天我了解到,这并不完全如此。

首先,CLR和框架是不同的东西,不一定走在一起。公共语言运行时(Common Language Runtime,CLR)是框架的关键部分,用于判断是否存在并行共存。今天只有4个版本的CLR:1.0,1.1,2.0和4:

所有共享相同的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在这个优秀的文章:

答案是:在目录“C:\ Program Files文件(x86)的\参考大会\微软\ Framework \ .NETFramework'是所有通过机器的版本的存档,并且Visual Studio使用这些! (为什么没有在一个地方拥有所有这些东西,并且真正并列共存呢?)

在所有这些答案之后,我更好地理解了发生了什么(顺便说一句,我发现那个最后一台机器确实安装了4.7的框架,因为我卸载了所有的,但是我打算在它上面安装Visual Studio Community 2017,并且取消了我的测试,但是Visual Studio安装程序已经安装好了,把最后一个框架放在机器上),当我在Windows XP SP3下执行应用程序时,它确实失败并不奇怪。但现在我知道该怎么做。

相关问题