【问题标题】:How to encrypt query string values passing from gridview in asp.net?如何加密从 asp.net 中的 gridview 传递的查询字符串值?
【发布时间】:2013-10-11 21:25:02
【问题描述】:

我想加密从 asp.net 中的网格视图行超链接选择传递的查询字符串值,因为以防止 SQL 注入攻击。我有兴趣在 UrlRewriting 方法或 Encryption 方法中完成这项工作。哪一种方法好用?该怎么做?

【问题讨论】:

  • 为什么要加密这些参数?
  • @DarinDimitrov 确保没有人摆弄查询字符串?
  • @Senthil Nathan:请使用向上箭头为您认为有价值的任何答案投票,并通过单击勾选接受最佳答案。

标签: asp.net


【解决方案1】:

以下代码将 "firstName=stephen&surname=oberauer" 转换为 "arg=x2lk1rkBmXvilYTzLpfm5E9tkYSzEZnSkl7se0hNP0HsXbD82OYfiA==" 并返回。

这是一个简单的加密/解密类(确保使用自己的密钥)

public static class Crypt
{
    // Must be random
    private static readonly byte[] key = new byte[24] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4 };

    public static string Encrypt(string input)
    {
        byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input);
        TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
        tripleDES.GenerateKey();
        tripleDES.Key = key;
        tripleDES.Mode = CipherMode.ECB;
        tripleDES.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tripleDES.CreateEncryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
        tripleDES.Clear();
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

    public static string Decrypt(string input)
    {
        byte[] inputArray = Convert.FromBase64String(input);
        TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
        tripleDES.Key = key;
        tripleDES.Mode = CipherMode.ECB;
        tripleDES.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tripleDES.CreateDecryptor();
        byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
        tripleDES.Clear();
        return UTF8Encoding.UTF8.GetString(resultArray);
    }
}

假设您有一个如下所示的网格视图:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
    <Columns>
        <asp:HyperLinkField DataNavigateUrlFields="Url" DataTextField="Name" />
    </Columns>
</asp:GridView>

你可以像这样设置你的网格数据:

var gridData = new[]
{  
    new { Name = "Link 1", Url = "TargetPage.aspx?arg=" + Crypt.Encrypt("firstName=stephen&surname=oberauer") },
    new { Name = "Link 2", Url = "TargetPage.aspx?arg=" + Crypt.Encrypt("firstName=joe&surname=smith") }
};
GridView1.DataSource = gridData;
GridView1.DataBind();

在您的目标页面中,您可以像这样解码加密的查询字符串:

var encryptedArgs = Request.QueryString["arg"];
var decryptedArgs = HttpUtility.ParseQueryString(Crypt.Decrypt(encryptedArgs));
FirstName.Text = decryptedArgs["firstName"];
Surname.Text = decryptedArgs["surname"];

为了确保您的查询字符串没有被篡改,您可以处理 Decrypt 方法引发的 FormatException 并进行测试以确保参数存在,在本例中为“firstName”和“surname”。

URL 重写是一个单独的问题,如果你想让你的 URL 更漂亮,你可以使用它。这与确保没有人摆弄查询字符串没有太大关系。

【讨论】:

    【解决方案2】:

    为什么要复杂,你可以使用行数据绑定事件来设置 Uri,转换你的查询字符串参数并使用 Server.UrlEncode,你很好

    RowDataBoundEvent


    protected void YourGrid_RowDataBound(object sender, GridViewRowEventArgs e)
            {
                try
                {
                    if (e.Row.RowType != DataControlRowType.DataRow) return;
    
                    if (e.Row.DataItem == null) return;
    
    
                    var hlobj= e.Row.FindControl("HYPERLINKID") as HyperLink;
    
                    if ( null == hlViewTest) return;
    
    
    
                    hlobj.NavigateUrl = String.Format("--------.aspx?whatever={0}",
                                                               Server.UrlEncode(Encrypt(whatever)));
                }
                catch (Exception ex)
                {
                   //
                }
    
    
            }
    

    加密方式:........


     private static string Encrypt(String val)
            {
                try
                {
                    var bytes = Encoding.UTF8.GetBytes(val.ToString(CultureInfo.InvariantCulture));
                    var encBytes = ProtectedData.Protect(bytes, new byte[0], DataProtectionScope.LocalMachine);
                    return Convert.ToBase64String(encBytes);
                }
                catch (Exception ex)
                {
                  return String.Empty;
                }
            }
    

    解密方法:------------


      private static string Decrypt(string val)
            {
                try
                {
                    var bytes = Convert.FromBase64String(val);
                    var encBytes = ProtectedData.Unprotect(bytes, new byte[0], DataProtectionScope.LocalMachine);
                    return System.Text.Encoding.UTF8.GetString(encBytes);
                }
                catch (Exception ex)
                {
                  return String.Empty;
                }
            }
    

    在其他 Page 中,使用 like.........

    var decryptedString=Decrypt(Request["YOUR PASSING ID"] || Request.QueryString["YOUR PASSING ID"]));
    

    【讨论】:

    • 感谢您的宝贵回答。它简化了我从网格视图选择中加密查询字符串值的编码。
    【解决方案3】:

    一种方法是为您要传递的每个 ID 创建一个 GUID,并在后端某处的 Dictionary 中保持跟踪。因此,您将查询字符串中的 Guid 传递并使用字典将其“解码”回普通 ID。

    但是,这是“默默无闻的安全”,因此您仍然需要在接收页面上执行授权检查(以确保没有人摆弄查询字符串。当然,猜测 GUID 正确的机会可能比被被雷击中了,还需要检查)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多