我们使用FormsAuthentication类在Classic ASP系统和.NET系统之间传递加密令牌.我们有一个由经典ASP系统调用的COM组件(.NET 2),并且该类直接在.NET中使用.
代码看起来像这样(没有硬编码的值):
FormsAuthentication.Initialize();
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "", new DateTime(2011, 1, 1), new DateTime(2012, 1, 1), false, "TEST");
var token = FormsAuthentication.Encrypt(ticket);
要解密,我们这样做:
var data = FormsAuthentication.Decrypt("E03519434CB6C157C24B5A1BFE3964537D9B0(SNIP)").UserData;
这两部分当前都在同一台服务器上运行,但是从这些系统在不同服务器上开始,我们设置了machineKey.一切都在.NET 3.5 / CLR 2中运行.
最近,我们已经将系统的.NET部分升级到.NET4.在本地,Classic ASP东西在另一台服务器上运行,因此,再次,我们在本地计算机(.NET)和服务器运行经典ASP素材.在32个64位v2 machine.configs和32个64位v4 machine.config中都设置了相同的machineKey(注意:对于某些旧式COM组件,我们以32位模式运行IIS).
在本地,我们在本地计算机(.NET 4)上运行的经典ASP系统(COM组件,在CLR 2中运行)上生成的令牌完全没有问题.但是,当我们刚开始将其推广到登台服务器时,会出现以下错误:
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType)
at System.Web.Security.FormsAuthentication.Decrypt(String encryptedTicket)
at NewMind.Tourism.DMS.Sso2.Sso.GetUserData(String dmsId, String token) in c:\CI\W\DMS-2.4-Release\NewMind.Tourism.DMS.Sso2\Sso.cs:line 131
at NewMind.Tourism.Core.Utils.SsoUtil.GetUserData(String token) in c:\CI\W\DMS-2.4-Release\NewMind.Tourism.Core\Utils\SsoUtil.cs:line 37
at NewMind.Tourism.Core.AuthenticationService.DoSsoLogin(String ssoToken, Action successAction, Action failureAction) in c:\CI\W\DMS-2.4-Release\NewMind.Tourism.Core\AuthenticationService.cs:line 126
我整个下午都在努力寻找原因.我找到了很多有关“ aspnet:UseLegacyEncryption”的文章,这些文章似乎可以解决许多问题,但这似乎对我们没有任何影响.我创建了一个小的测试脚本,该脚本试图解密在本地计算机上生成的两个令牌(.NET 2中的一个令牌,.NET 4中的一个令牌),然后在两台计算机上的两个CLR中运行它:
>在我的机器上,CLR 2 **有效**
>在我的机器上,CLR 4 **有效**
>阶段服务器,CLR 2 **有效**
>阶段服务器,CLR 4 **错误**
>阶段服务器,CLR 4,aspnet:UseLegacyEncryption = true **错误**
我的想法已经用完了.我不太确定该怎么做.我已经三重检查了machineKeys完全相同. UserLegacyEncryption选项似乎没有什么不同.我无法比较在每台计算机/ CLR上生成的令牌,因为它们每次都不同.我们不知道为什么完全相同的代码可以在我们的开发机上的完全相同的.NET框架版本上工作.
我们的备份计划是创建COM组件的CLR 4版本,或完全更改加密,但是我们真的很想了解问题并进行修复.
解决方法:
原来我们缺少一个补丁.服务器通常已完全修补,但是由于.NET 4只是最近才安装的,并且之后没有进行修补,因此我们缺少更改加密的修补程序(由于使用了ASP.NET漏洞).
感谢Damian Edwards levib @ MS的帮助!