Encrypting Query Strings
英文源文档 <http://www.codeproject.com/KB/aspnet/urlquerystring-encryption.aspx>
翻译: 白水<敏捷学院>
代码下载:QueryStringEncryption.zip
介绍
我们经常在两个页面之间使用键值对的查询字符串形式传递一些值。Query String 是在网页之间传输数据的最简单的方式。在查询字符串中传递的数据都是明文数据,而且用户可能会改变传递的值,这将会导致系统的安全性和数据的完整性。
解决方案
针对这个问题,我开发了一个小的代码片段用来对查询字符串(QueryString)进行加密和解密。因此,URL看起来是这样的:
http://<Web Address>/Page2.aspx?Q5vcD9JTYpWVEowhCJ/PMAjkzatZ22ouiESQebrzyjx0IhRCEZigHp3YMVRwkAXD.
代码使用
在这个简单的应用中,我创建了两个页面Page1.aspx和Page2.aspx,类EncryptDecryptQueryString.cs 用来加密和解密。
Page1.aspx 允许用户提交3个字段,并将加密后的值以QueryString的方式发送到Page2.aspx。在Page2.aspx中解密接收到的QueryString值,并将原始值显示在Label控件中。
值得关注的是如何对QueryString进行加密和解密。
The class - EncryptDecryptQueryString.cs
public class EncryptDecryptQueryString
{
private byte[] key = { };
private byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef };
public string Decrypt(string stringToDecrypt, string sEncryptionKey)
{
byte[] inputByteArray = new byte[stringToDecrypt.Length + 1];
try
{
key = System.Text.Encoding.UTF8.GetBytes(sEncryptionKey);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
inputByteArray = Convert.FromBase64String(stringToDecrypt);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,
des.CreateDecryptor(key, IV), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
return encoding.GetString(ms.ToArray());
}
catch (Exception e)
{
return e.Message;
}
}
public string Encrypt(string stringToEncrypt, string SEncryptionKey)
{
try
{
key = System.Text.Encoding.UTF8.GetBytes(SEncryptionKey);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,
des.CreateEncryptor(key, IV), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
catch (Exception e)
{
return e.Message;
}
}
}
这个类有两个方法,一个加密一个解密。这两个方法都是使用一个钥匙key对字符串进行加密和解密操作。
Page1.aspx:这个页面有3个字段。当用户填充数据并提交数据将加密的字符串发送到Page2.aspx。如下代码所示:
protected void btnSubmit_Click(object sender, EventArgs e)
{
string strName = "", strAge = "", strPhone = "";
strName = txtName.Text;
strAge = txtAge.Text;
strPhone = txtPhone.Text;
string strURL = "Page2.aspx?";
if (HttpContext.Current != null)
{
string strURLWithData = strURL +
EncryptQueryString(string.Format("Name={0}&Age={1}&Phone={2}",
strName, strAge, strPhone));
HttpContext.Current.Response.Redirect(strURLWithData);
}
else
{ }
}
public string EncryptQueryString(string strQueryString)
{
EncryptDecryptQueryString objEDQueryString = new EncryptDecryptQueryString();
return objEDQueryString.Encrypt(strQueryString, "r0b1nr0y");
}
注意上面的代码片段,如何使用钥匙key "r0b1nr0y"对数据进行加密的。你可以使用长度是8的任意字符串作为key来使用。解密数据也是一样。
Page2.aspx: 这个页从URL接收数据并解密。如下代码所示:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string strReq = "";
strReq = Request.RawUrl;
strReq = strReq.Substring(strReq.IndexOf('?') + 1);
if (!strReq.Equals(""))
{
strReq = DecryptQueryString(strReq);
//Parse the value... this is done is very raw format..
//you can add loops or so to get the values out of the query string...
string[] arrMsgs = strReq.Split('&');
string[] arrIndMsg;
string strName = "", strAge = "", strPhone = "";
arrIndMsg = arrMsgs[0].Split('='); //Get the Name
strName = arrIndMsg[1].ToString().Trim();
arrIndMsg = arrMsgs[1].Split('='); //Get the Age
strAge = arrIndMsg[1].ToString().Trim();
arrIndMsg = arrMsgs[2].Split('='); //Get the Phone
strPhone = arrIndMsg[1].ToString().Trim();
lblName.Text = strName;
lblAge.Text = strAge;
lblPhone.Text = strPhone;
}
else
{
Response.Redirect("Page1.aspx");
}
}
}
private string DecryptQueryString(string strQueryString)
{
EncryptDecryptQueryString objEDQueryString = new EncryptDecryptQueryString();
return objEDQueryString.Decrypt(strQueryString, "r0b1nr0y");
}
本示例使用.NET2008开发的Web应用程序。
结论
所以,我们现在可以发送加密的数据然后在目标页解密数据。这样数据在传送过程从不会很容易的被篡改,因而安全性和应用程序数据的完整性不受损害。希望你喜欢这篇文章。快乐编程!