我想加密查询字符串值传递从网格视图行超链接选择在asp.net中,因为防止SQL注入攻击。我有兴趣在url重写方法或加密方法中做这项工作。哪一种方法比较好?怎么做呢?
下面的代码将"firstName=stephen&;姓氏=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"one_answers"姓氏"。
URL重写是一个单独的问题,如果你想让你的URL更漂亮,你可以使用它。它与确保没有人篡改查询字符串没有太大关系。
为什么要复杂化,您可以使用行数据绑定事件来设置Uri,转换您的querystring参数并使用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;
}
}
在其他页面,使用.........
var decryptedString=Decrypt(Request["YOUR PASSING ID"] || Request.QueryString["YOUR PASSING ID"]));
一种方法是为要传递的每个ID创建一个GUID,并在后端某处的Dictionary中保持跟踪。因此,您在querystring中传递Guid,并使用字典将其"解码"回正常ID。
然而,这是"模糊安全",所以你仍然需要在接收页面上执行授权检查(以确保没有人篡改查询字符串)。当然,猜对GUID的机会可能比被闪电击中要小,但您仍然需要检查。