2014-01-23 47 views
1

我想要完成的是在我的MVC应用程序中使用相同的接口和其他一些方法创建cookie对象/方法的替代品。如何扩展MVC5中的HttpCookie对象?

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

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

+0

你可以尝试在现有的Cookie类上使用扩展方法。 –

+0

我知道这存在的Web API。也许你可以适应MVC? http://www.asp.net/web-api/overview/working-with-http/http-cookies –

回答

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中进行解密。有一件事很好,它会自动生成IV和HMAC,以验证没有篡改cookie值。您将需要两个单独的密钥,一个用于HMAC,一个用于加密。因为它们是加密系统中最重要的部分,所以能够明智地生成它们。

您可以Encrypt and decrypt a string下找到加密类或者你可以用你想,如果有什么东西你公司专门用来使用任何覆盖。

最后用简单的创建一个加密的Cookie,并把它添加到响应:

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

当你想解密简单地把饼干回加密的Cookie:

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

这是非常接近我的目标。唯一缺少的是如何使它自动确定它是否是加密的cookie并自动执行解密。 – Hades

+0

你将无法做到这一点,因为它将被混合到具有未加密cookie的cookie集合中。你可以在技术上杜绝isencrypted属性,然后投所有的cookie加密Cookie,但会带来不必要的开销和额外的代码,我想你想避免.. – nerdybeardo

+0

难道在HTTP处理程序层面上做了什么?例如,在我想要加密的任何cookie中,我只需在cookie名称上设置一个字符串前缀即可。然后,任何具有该处理程序前缀的cookie都可以通过请求/响应管道自动加密/解密。那有意义吗? 我正在寻找一种方法让我的项目开发人员不必真的想太多。 – Hades

0

我不相信有一种方法。揭示Cookie实例的HttpRequest/HttpResponse对象都是密封的,因为它本身就是HttpCookie类。

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

祝你好运!

+0

感谢您的回复。上面的nerdybeardo的答案更接近我正在寻找...看到评论那里的更多细节:) – Hades