1

我有我只想在三个不同的 HTTP POST 中提供的数据(想想工作流),我不想使用 QueryString 或 Cookie 来获取此信息。出于这个原因,我认为 _viewstate 的概念在这里适用。

  1. 那么,我应该如何将 ASP.NET MVC 中的 ViewState 模拟为包含机密性和身份验证 的加密隐藏字段?

  2. ASP.NET 4 或更新的框架是否包含这个?

更多信息

ASP.NET 使用加密的 Viewstate 作为表单中的隐藏字段。这样做的好处之一是加密是“经过身份验证的”,这意味着除了加密有效负载中可用的隐私功能之外,还可以检测到任何篡改。

这个站点上有很多问题讨论如何将 Viewstate 改造成 ASP.NET MVC,但我没有看到任何答案涉及将包含这些功能的数据加密到序列化数据:

  • 机密性(隐私)
  • 身份验证(无修改)
4

1 回答 1

1

它不是“经典 ASP”(这是 1997 年到 2003 年间流行的重 COM、对 VBScript 友好的平台),而是使用 ViewState 的 ASP.NET WebForms。ViewState 本身是页面控件属性的 Base64 编码(未加密)表示。这样做是因为 HTML 表单不会将其他属性传输回服务器,只有<input>s'value=""属性,因此 ViewState 包含控件的背景颜色属性(如果已设置)等内容。

在 WebForms 中,开发人员可以使用 ViewState 验证 MAC 来确保他们的 viewstate 数据不会被更改,但实际上它经常发生故障。如果您搜索“视图状态 MAC 验证失败”,那么您会发现无数关于如何解决该问题的讨论。然而,这在我的帖子中是无关紧要的。

如果您想将客户端表单字段用作往返数据向量,那很好,只需执行以下代码即可。

class PageViewModel {
    public String SecretData;
}

public ActionResult Foo() {

    Byte[] someSecretData = GetIcbmLaunchCodes();
    someSecretData = ArbitraryEncryptionAlgorithm( someSecretData ); // you can encrypt the data any way you want. I personally recommend a symmetric algorithm like AES or TripleDES.

    HashAlgorithm hashAlgo = new HMACSHA1();
    hashAlgo.Key = /* Your private key for HMAC */
    Byte[] hmac = hashAlgo.ComputeHash( someSecretData );

    // when using SHA1, hmac will be 160 bits long, or 20 bytes.
    PageViewModel model = new PageViewModel();
    model.SecretData = Convert.ToBase64String( hmac + someSecretData ); // array concatenation is an exercise for the reader
    return View( model );
}

[HttpPost]
public ActionResult Foo(PageViewModel model) {

    Byte[] postedData = Convert.FromBase64String( model.SecretData );

    Byte[] hmac = postedData[0...20]; // array substring is an exercise for the reader
    Byte[] secretData = postedData[20...n];

    // Now verify the secret data
    HashAlgorithm hashAlgo = new HMACSHA1();
    hashAlgo.Key = /* Your private key for HMAC */
    Byte[] hmac2 = hashAlgo.ComputeHash( secretData );

    if( hmac2 != hmac ) {
        /* the data has been tampered with. */
    } else {
        /* the data is unadulterated */

        Byte[] originalSecretData = ArbitaryDecryptionAlgorithm( secretData );
    }

}
于 2013-01-31T05:53:16.367 回答