我们使用 FormsAuthentication
类在经典 ASP 系统和 .NET 系统之间传递加密 token 。我们有一个由 Classic 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 部分升级到 .NET 4。在本地,Classic ASP 的东西在另一台服务器上运行,所以我们再次在本地机器上设置了相同的 machineKey (.NET ) 和运行经典 ASP 内容的服务器。在 32+64 位 v2 machine.configs 和 32+64 位 v4 machine.config 中都设置了相同的 machineKey(注意:对于某些遗留 COM 组件,我们在 32 位模式下运行 IIS)。
在本地,我们在本地机器 (.NET 4) 上运行的经典 ASP 系统(COM 组件,在 CLR 2 中运行)生成的 token 完全没有问题。但是,当我们刚开始将其部署到暂存服务器时,出现以下错误:
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”,这似乎解决了很多问题,但这对我们来说似乎没有任何区别。我创建了一个小测试脚本,它试图解密在我的本地机器上生成的两个 token (一个在 .NET 2 中,一个在 .NET 4 中),并在两台机器上的两个 CLR 中运行它:
- 在我的机器上,CLR 2 ** 有效 **
- 在我的机器上,CLR 4 ** 有效 **
- 阶段服务器,CLR 2 ** 有效 **
- 阶段服务器,CLR 4 ** 错误 **
- 阶段服务器,CLR 4,aspnet:UseLegacyEncryption=true ** 错误 **
我已经没有想法了。我不太确定要尝试什么。 machineKeys 都是相同的,我已经三重检查了。 UserLegacyEncryption 选项似乎没有什么不同。我无法比较在每台机器/CLR 上生成的 token ,因为它们每次都不同。我们不知道为什么完全相同的代码可以在我们开发机器上完全相同版本的 .NET 框架上运行。
我们的备份计划是创建 COM 组件的 CLR 4 版本,或者完全更改加密,但我们真的很想了解问题并能够修复它。
最佳答案
原来我们缺少一个补丁。服务器通常已完全打补丁,但由于 .NET 4 是最近才安装的,之后没有打补丁,因此我们缺少更改加密的补丁(由于 ASP.NET 漏洞)。
感谢 Damian Edwards + levib @MS 的协助!
关于c# - ASP.NET FormsAuthentication - 要解密的数据长度无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7728658/