如何在MVC5中扩展HttpCookie对象?

时间:2014-01-23 09:38:29

标签: c# asp.net-mvc cookies encryption httpcookie

我正在努力实现的目的是创建一个替代我的MVC应用程序中的Cookie对象/方法,它使用相同的接口和一些其他方法。

我想添加的方法是创建加密cookie的自定义方法。这些方法基本上只是在设置之前加密cookie中设置的数据。反向方法会在读取cookie后解密数据。

我想替换Cookie对象内置的原因是我可以重新设计默认方法的行为以允许自动加密/解密。

2 个答案:

答案 0 :(得分:1)

虽然HttpCookie类是密封的并且无法继承,但您可以通过使用操作符重载的加密cookie类来简化您的生活,以便于使用。

public class EncryptedCookie
{
    public string Name { get; set; }

    public string Value { get; set; }

    private byte[] encryptionKey;

    private byte[] hmacKey;

    public EncryptedCookie()
    {
        // setup keys
        encryptionKey = Convert.FromBase64String(ConfigurationManager.AppSettings["encryption-key"]);
        this.hmacKey = Convert.FromBase64String(ConfigurationManager.AppSettings["hmac-key"]);
    }

    public static explicit operator HttpCookie(EncryptedCookie cookie)
    {
        if (string.IsNullOrEmpty(cookie.Name))
        {
            throw new ArgumentException("Encrypted cookie must have a name");
        }

        if (string.IsNullOrEmpty(cookie.Value))
        {
            throw new ArgumentException("Encrypted cookie must have a value");
        }

        return new HttpCookie(cookie.Name, cookie.Encrypt());
    }

    public static explicit operator EncryptedCookie(HttpCookie cookie)
    {
        if (cookie == null)
        {
            return null;
        }

        var result = new EncryptedCookie { Name = cookie.Name };
        result.Decrypt(cookie.Value);
        return result;
    }

    private string Encrypt()
    {
        var encryptor = new Encryptor<AesEngine, Sha256Digest>(Encoding.UTF8, this.encryptionKey, this.hmacKey);
        return encryptor.Encrypt(this.Value);
    }

    private void Decrypt(string cookieValue)
    {
        var encryptor = new Encryptor<AesEngine, Sha256Digest>(Encoding.UTF8, this.encryptionKey, this.hmacKey);
        string plainText = encryptor.Decrypt(cookieValue);
        if (string.IsNullOrEmpty(plainText))
        {
            throw new ArgumentException();
        }

        this.Value = plainText;
    }
}

要使用此课程,您需要我的加密课程以及bouncycastle。当从响应中已有的http cookie设置时,此类对您输入的任何值和解密进行加密。对此有一点好处是它将自动为您和HMAC生成IV以验证没有篡改cookie值。您需要两个单独的键,一个用于HMAC,另一个用于加密。明智地生成这些,因为它们是加密系统中最重要的部分。

您可以在Encrypt and decrypt a string下找到加密器类,或者如果您的公司专门使用某些内容,您可以覆盖您想要使用的任何内容。

最后使用只需创建一个加密的cookie并将其添加到响应中:

EncryptedCookie cookie = new EncryptedCookie { Name = "MyCookie", Value = "Hide this!" };
Response.Cookies.Add((HttpCookie)cookie);

当你想要解密时,只需将cookie转换回加密的cookie:

var cookie = (EncryptedCookie)Request.Cookies["MyCookie"];
Response.Write(cookie.Value);

答案 1 :(得分:0)

我不相信有办法。暴露Cookie实例的HttpRequest / HttpResponse对象都是密封的,就像HttpCookie类本身一样。

您可以通过使用HttpResponseWrapper / HttpRequestWrapper基类重新实现请求/响应来解决这个问题,但这似乎很有用。

祝你好运!