你还在错误地用 EnableViewStateMac 解决群集服务器中的 MAC 失败?

作者:vkvi 来源:千一网络(原创) 日期:2011-4-16

在网络场或群集中,或者在某些做了 CDN 加载的虚拟主机中,常常会出现 Cookie 提前过期、验证试图状态 MAC 失败这类的错误。

有人给的解决方案是:web.config 里加 EnableEventValidation="false" EnableViewStateMac="false" ViewStateEncryptionMode="Never"。

这个方案也太……既然出错,那咱就不用了吧。怎么能这样呢?出错就不用了?出错得解决问题。

错误原因

ASP.NET 中有很多涉及到加密的东西,比如 ViewState,比如 FormsAuthenticationTicket,这些东西都是要传送到客户端的,加密才能保障其安全性。

加密就得有个私钥,但这个私钥我们并没有指定啊,那是因为 ASP.NET 自动生成的。

但是如果是在网络场或群集中,或者在某些做了 CDN 加载的虚拟主机中,由于涉及到多台服务器 ASP.NET 就无法为各台机器自动生成相同的私钥,这就造成了这个服务器产生的数据,那台服务器解析不出来。于是就出错了。

怎么办?

既然 ASP.NET 在多台服务器上无法自动随机生成相同的私钥,那只有我们自己指定了。

在 web.config 的 configuration/system.web/ 下配置

  • decryption 解密算法。可选值:Auto(默认)、AES、3DES。(在 .NET Framework 1.1 及以下版本中,没有此属性)
  • decryptionKey 加解密密钥。这里要自己手动设置为十六进制字符串,长度根据所选密钥设定。
  • validation 验证算法。可选值:AES、MD5、SHA1(默认)、3DES
  • validationKey 验证密钥,用来创建 MAC(消息身份验证代码),以保证视图状态未被更改。这里要自己手动设置为十六进制字符串,长度根据所选密钥设定。

MSDN 上说,.NET Framework 2.0 及以后版本中 validation 的 3DES 用 TripleDES 代替,但我实际使用中发现,在 web.config 中,仍然不能用 TripleDES,仍然是 3DES。

关于密钥长度

对于 decryptionKey

  • 如果 decryption 值为 DES,则 decryptionKey 应为 16 个十六进制字符长,即 8 个字节。(这个现在已经不用了)
  • 如果 decryption 值为 AES、3DES,则 decryptionKey 应为 48 个十六进制字符长,即 24 个字节。

对于 validationKey

  • 不论 validation 为何值,validationKey 应为 40 到 128 个十六进制字符长,即 20 到 64 个字节。建议选用 SHA1(MD5 虽然性能好些,但安全性要比 SHA1 差些)。

关于这些加密,请参见千一网络的连载文章 C# 加密

更多关于 machineKey,请参见 http://msdn.microsoft.com/zh-cn/library/w8h3skw9(VS.80).aspx

要了解创建 machineKey 的代码及使用该工具,请参见创建生成 MachineKey 的代码

相关文章