65.9K
CodeProject 正在变化。 阅读更多。
Home

加密查询字符串

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (37投票s)

2009年2月13日

CPOL

2分钟阅读

viewsIcon

216076

downloadIcon

4792

查询字符串的加密和解密。

引言

我们经常以键值对的形式通过查询字符串在页面之间传递值。 查询字符串是在网页之间传输小数据片段的最简单、应用最广泛的机制。 我观察到并遇到了在查询字符串中传递可读文本/数据的问题。 最终用户可能会更改查询字符串中的值以玩弄应用程序,同时,这也会损害系统的安全性和数据完整性。

解决方案

我处理了这个问题,并开发了一个小代码片段,用于使用指定的密钥加密和解密查询字符串。 因此,URL 看起来像 http://<Web 地址>/Page2.aspx?Q5vcD9JTYpWVEowhCJ/PMAjkzatZ22ouiESQebrzyjx0IhRCEZigHp3YMVRwkAXD

使用代码

在示例应用程序中,我开发了两个页面,Page1.aspxPage2.aspx,此外还有一个用于加密和解密的类 EncryptDecryptQueryString.cs

Page1.aspx 包含三个字段,供用户填写,提交表单后,这些字段中的值会以加密的查询字符串的形式发送到 Page2.aspx。 在 Page2.aspx 中,查询字符串被解密,并检索原始值以显示在标签中。

我想提到的重要事实是,一个密钥用于加密和解密查询字符串数据。

- 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;
        }
    } 
}

在上面的类中,你会发现有两个方法,一个用于加密,另一个用于解密。 请注意,除了用于执行加密或解密操作的密钥之外,这些方法还接受要加密或解密的字符串。 这个密钥需要保密,并且应该使用相同的密钥来执行这两个操作。

Page1.aspx:此页面有三个字段。 当用户填写数据并提交按钮时,从字段中检索数据并加密,然后发送到 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");
}

注意在上面的代码片段中,数据是如何使用密钥“r0b1nr0y”检索和加密的。 你可以使用任何长度为 8 个字符的密钥进行加密,并使用相同的密钥进行解密。

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");
}

你可以浏览附带的项目以获取整个解决方案并更好地理解它。 请注意,示例 Web 应用程序是使用 .NET 2008 开发的。

结论

因此,我们现在可以使用加密格式的查询字符串发送数据,并在目标页面中解密它以获取原始数据。 篡改查询字符串中的数据并不容易,因此不会损害应用程序数据的安全性和完整性。 希望你喜欢这篇文章。 编程愉快!!!

© . All rights reserved.