2

我正在加密 MVC url 中的参数..例如

http:/localhost:xxxx/Movies/Edit/1,加密参数值1,赋值给id。

基本上我遵循的是实现自定义操作链接,该链接将RoutedValueDictionary基于盐字符串加密值并使用相同的文本作为加密值的前缀,Encrypt_这样输出将是Encrypt_dfhwo=23nbsdkfhskdf

所以网址是

http:/localhost:xxxx/Movies/Edit/Encrypt_dfhwo=23nbsdkfhskdf

已实现DefaultControllerFactory.CreateController,我正在检查路由值是否以前缀 Encrypt_ 开头,然后解密该值,然后传递给控制器​​。

一切正常。我看到的问题是,如果黑客操纵 url 并将 url 更改为http:/localhost:xxxx/Movies/Edit/5(随机数,与数据库中的记录匹配),那么我的控制器将在没有任何解密机制的情况下处理请求。

如何克服这个问题..你们在这里看到任何潜在的漏洞吗?

任何建议都是最受欢迎的。

4

2 回答 2

1
  1. 你通过加密数据库记录得到什么?看起来该值仍然可以重播。
  2. 如果您只想通过加密值访问记录,请在您的操作中解密它而不是在它之前,并且不要仅通过您的操作中的数字来允许它,
  3. 黑客仍然可以发送随机值,只允许加密值,并且仍然学会加密他们想要的任何值,有很多侧通道攻击的可能性,在这种情况下你需要使用Authenticated Encryption 。
  4. 您应该使用 url-safe base 64,您的示例看起来并非如此。

如果您想要的只是某人无法随机猜测记录值,请使用高级加密框架,该框架为您提供更少的选择以减少加密错误。我将 Google 的Keyczar 移植到 C#中,这样 C# 就会有这样的框架。它具有经过身份验证的加密,可为标题、随机 IV 和标签的加密添加 41 个字节,默认情况下使用 Web 安全 base64。

于 2013-02-25T14:08:45.473 回答
0
**Add A Folder with two classes 
Class 1 : EncryptedActionParameterAttribute

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.Mvc;

namespace MVCInvoicClient.Extensions
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class EncryptedActionParameterAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

            Dictionary<string, object> decryptedParameters = new Dictionary<string, object>();
            if (HttpContext.Current.Request.QueryString.Get("q") != null)
            {
                string encryptedQueryString = HttpContext.Current.Request.QueryString.Get("q");
                string decrptedString = Decrypt(encryptedQueryString.ToString());
                string[] paramsArrs = decrptedString.Split('?');

                for (int i = 0; i < paramsArrs.Length; i++)
                {
                    string[] paramArr = paramsArrs[i].Split('=');
                    decryptedParameters.Add(paramArr[0], Convert.ToInt32(paramArr[1]));
                }
            }
            for (int i = 0; i < decryptedParameters.Count; i++)
            {
                filterContext.ActionParameters[decryptedParameters.Keys.ElementAt(i)] = decryptedParameters.Values.ElementAt(i);
            }
            base.OnActionExecuting(filterContext);

        }

        private string Decrypt(string encryptedText)
        {

                string key = "jdsg432387#";
                byte[] DecryptKey = { };
                byte[] IV = { 55, 34, 87, 64, 87, 195, 54, 21 };
                byte[] inputByte = new byte[encryptedText.Length];

                DecryptKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8));
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                inputByte = Convert.FromBase64String(encryptedText);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(DecryptKey, IV), CryptoStreamMode.Write);
                cs.Write(inputByte, 0, inputByte.Length);
                cs.FlushFinalBlock();
                System.Text.Encoding encoding = System.Text.Encoding.UTF8;
                return encoding.GetString(ms.ToArray());
        }

    }
}


class 2 : MyExtensions

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCInvoicClient.Extensions
{
    public static class MyExtensions
    {
        public static MvcHtmlString EncodedActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
        {
            string queryString = string.Empty;
            string htmlAttributesString = string.Empty;
            if (routeValues != null)
            {
                RouteValueDictionary d = new RouteValueDictionary(routeValues);
                for (int i = 0; i < d.Keys.Count; i++)
                {
                    if (i > 0)
                    {
                        queryString += "?";
                    }
                    queryString += d.Keys.ElementAt(i) + "=" + d.Values.ElementAt(i);
                }
            }

            if (htmlAttributes != null)
            {
                RouteValueDictionary d = new RouteValueDictionary(htmlAttributes);
                for (int i = 0; i < d.Keys.Count; i++)
                {
                    htmlAttributesString += " " + d.Keys.ElementAt(i) + "=" + d.Values.ElementAt(i);
                }
            }

            //<a href="/Answer?questionId=14">What is Entity Framework??</a>
            StringBuilder ancor = new StringBuilder();
            ancor.Append("<a ");
            if (htmlAttributesString != string.Empty)
            {
                ancor.Append(htmlAttributesString);
            }
            ancor.Append(" href='");
            if (controllerName != string.Empty)
            {
                ancor.Append("/" + controllerName);
            }

            if (actionName != "Index")
            {
                ancor.Append("/" + actionName);
            }
            if (queryString != string.Empty)
            {
                ancor.Append("?q=" + Encrypt(queryString));
            }
            ancor.Append("'");
            ancor.Append(">");
            ancor.Append(linkText);
            ancor.Append("</a>");
            return new MvcHtmlString(ancor.ToString());
        }

        private static string Encrypt(string plainText)
        {
            string key = "jdsg432387#";
            byte[] EncryptKey = { };
            byte[] IV = { 55, 34, 87, 64, 87, 195, 54, 21 };
            EncryptKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8));
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByte = Encoding.UTF8.GetBytes(plainText);
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, des.CreateEncryptor(EncryptKey, IV), CryptoStreamMode.Write);
            cStream.Write(inputByte, 0, inputByte.Length);
            cStream.FlushFinalBlock();
            return Convert.ToBase64String(mStream.ToArray());
        }               
    }
}

**Controller** 

Add this line above the controller class Example for your Index
 [EncryptedActionParameter]

**In your View** 

 @Html.EncodedActionLink("Download Invoice", "FileDownload","DataFiles", new { id = item.DataFilesID }, null)

add a using statement 

@using MVCInvoicClient.Extensions
于 2015-07-29T10:17:04.337 回答