Skip to content

FormsAuthentication.Decrypt 在执行加密操作时出错(CryptographicException)

使用 FormsAuthentication 来记住登录状态,但是在隔一段时间(不确定是不是 Session 的过期时间)或者服务器重启后,通过 FormsAuthentication.Decrypt 解密 ticket 时,会发生 CryptographicException :在执行加密操作时出错 的异常。

最终在 StackOverflow 上发现了这个问题 How to explicitly specify MachineKey with FormsAuthentication.Decrypt() ,让我想起了站点升级前是在 web.config 中使用了固定的 machineKey 的,把相关的配置复制过来果然就好了。

xml
<configuration>
  <system.web>
    <machineKey
        validationKey="4BD24FACB40328C908CB83BD95FCB80C6DBBDAED3914A1CB2B5938601187142F2BD89C211F5F2CDD70D26A7BDB5E939576EB12A3297645F6BE099D3192258409"
        decryptionKey="A68B71A88B6939904765DA47B086803F1777D2C6E3DB899DF7A67AC518C3258A"
        validation="SHA1"
        decryption="AES" />
  </system.web>
</configuration>

<machineKey> 总共有 4 个属性:

AttributeDescription
decryptionAn algorithm which performs encryption and decryption using a symmetric key.
decryptionKeyA hex string specifying the key used by instances of the decryption algorithm.
validationAn algorithm which generates a message authentication code over some payload.
validationKeyA hex string specifying the key used by instances of the validation algorithm.

其中 decryptionKeyvalidationKey 的格式如下:

js
key-format = (hex-string | ("AutoGenerate" [",IsolateApps"] [",IsolateByAppId"]))
  • solateApps – The runtime uses the value of HttpRuntime.AppDomainAppVirtualPath to transform the auto-generated key. If multiple applications are hosted on the same port in IIS, the virtual path is sufficient to differentiate them.
  • IsolateByAppId – The runtime uses the value of HttpRuntime.AppDomainAppId to transform the auto-generated key. If two distinct applications share a virtual path (perhaps because those applications are running on different ports), this flag can be used to further distinguish them from one another. The IsolateByAppId flag is understood only by the ASP.NET 4.5, but it can be used regardless of the compatibilityMode setting (which will be introduced in tomorrow’s post).

decryptionKeyvalidationKey 设置为如下 3 种格式时,均会在重启站点后解密失败,只有设置成固定的 hex-string 才 OK。

  • validationKey="AutoGenerate" decryptionKey="AutoGenerate"
  • validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps"
  • validationKey="AutoGenerate,IsolateByAppId" decryptionKey="AutoGenerate,IsolateByAppId"

网上找到一个在线自动生成工具 => MachineKey 生成工具

参考

  1. How to explicitly specify MachineKey with FormsAuthentication.Decrypt()
  2. Cryptographic Improvements in ASP.NET 4.5, pt. 1
  3. Cryptographic Improvements in ASP.NET 4.5, pt. 2
  4. Cryptographic Improvements in ASP.NET 4.5, pt. 3