【问题标题】:How can I encrypt a querystring in asp.net?如何在 asp.net 中加密查询字符串?
【发布时间】:2010-09-19 10:27:24
【问题描述】:

我需要在 ASP.NET 中加密和解密查询字符串。

查询字符串可能如下所示:

http://www.mysite.com/report.aspx?id=12345&year=2008

如何加密整个查询字符串,使其看起来像下面这样?

http://www.mysite.com/report.aspx?crypt=asldjfaf32as98df8a

然后,当然,我如何解密它?对于这样的事情,最好的加密是什么?三重DES?

【问题讨论】:

    标签: asp.net encryption


    【解决方案1】:

    这是一种在 VB 中实现的方法来自:http://www.devcity.net/Articles/47/1/encrypt_querystring.aspx

    加密代码的包装器:将您的查询字符串参数传递到此,并更改密钥!!!

    Private _key as string = "!#$a54?3"
    Public Function encryptQueryString(ByVal strQueryString As String) As String
        Dim oES As New ExtractAndSerialize.Encryption64()
        Return oES.Encrypt(strQueryString, _key)
    End Function
    
    Public Function decryptQueryString(ByVal strQueryString As String) As String
        Dim oES As New ExtractAndSerialize.Encryption64()
        Return oES.Decrypt(strQueryString, _key)
    End Function
    

    加密代码:

    Imports System
    Imports System.IO
    Imports System.Xml
    Imports System.Text
    Imports System.Security.Cryptography
    
    Public Class Encryption64
        Private key() As Byte = {}
        Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
    
        Public Function Decrypt(ByVal stringToDecrypt As String, _
            ByVal sEncryptionKey As String) As String
            Dim inputByteArray(stringToDecrypt.Length) As Byte
             Try
                key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
                Dim des As New DESCryptoServiceProvider()
                inputByteArray = Convert.FromBase64String(stringToDecrypt)
                Dim ms As New MemoryStream()
                Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), _
                    CryptoStreamMode.Write)
                cs.Write(inputByteArray, 0, inputByteArray.Length)
                cs.FlushFinalBlock()
                Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
                Return encoding.GetString(ms.ToArray())
            Catch e As Exception
                Return e.Message
            End Try
        End Function
    
        Public Function Encrypt(ByVal stringToEncrypt As String, _
            ByVal SEncryptionKey As String) As String
            Try
                key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
                Dim des As New DESCryptoServiceProvider()
                Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes( _
                    stringToEncrypt)
                Dim ms As New MemoryStream()
                Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), _
                    CryptoStreamMode.Write)
                cs.Write(inputByteArray, 0, inputByteArray.Length)
                cs.FlushFinalBlock()
                Return Convert.ToBase64String(ms.ToArray())
            Catch e As Exception
                Return e.Message
            End Try
        End Function
    
    End Class
    

    【讨论】:

    • 这几乎可以工作。我更改了这两行: Return Server.UrlEncode(enc64.Encrypt(qs, _key)) 和 Return Server.UrlDecode(enc64.Decrypt(qs, _key)) 并且不要打扰 Replace(" ", "+" )
    • 另外,用法(哦,我多么希望我可以编辑):加密:Dim myQS = EncryptQueryString("id=12345&year=2008") Response.Redirect(String.Format("Default.aspx? q={0}", myQS)) 解密:Dim myQS As String = DecryptQueryString(Request.QueryString("q"))
    • 有没有其他方法可以进行加密但又不会使 url 太长?!有时,如果有很多查询字符串会使 url 超过 2000 个字符,并且对大多数浏览器不利
    【解决方案2】:

    在 C# 中使用 AES 加密进行加密-

    protected void Submit(object sender, EventArgs e)
    {
        string name = HttpUtility.UrlEncode(Encrypt(txtName.Text.Trim()));
        string technology = HttpUtility.UrlEncode(Encrypt(ddlTechnology.SelectedItem.Value));
        Response.Redirect(string.Format("~/CS2.aspx?name={0}&technology={1}", name, technology));
    }
    

    AES算法加解密函数

    private string Encrypt(string clearText)
    {
        string EncryptionKey = "hyddhrii%2moi43Hd5%%";
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }
        return clearText;
    }
    
    
    private string Decrypt(string cipherText)
    {
        string EncryptionKey = "hyddhrii%2moi43Hd5%%";
        cipherText = cipherText.Replace(" ", "+");
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.Close();
                }
                cipherText = Encoding.Unicode.GetString(ms.ToArray());
            }
        }
        return cipherText;
    }
    

    解密

    lblName.Text = Decrypt(HttpUtility.UrlDecode(Request.QueryString["name"]));
    lblTechnology.Text = Decrypt(HttpUtility.UrlDecode(Request.QueryString["technology"]));
    

    【讨论】:

      【解决方案3】:

      我无法在脑海中为您提供交钥匙解决方案,但您应该避免使用 TripleDES,因为它是 not as secure as other encryption methods

      如果我这样做,我只需将整个 URL(域和查询字符串)作为 URI object,使用 built-in .NET libraries 之一对其进行加密,并将其作为 crypt 对象提供。当我需要解密它时,这样做,然后创建一个新的 URI 对象,它可以让您从原始查询字符串中取回所有内容。

      【讨论】:

        【解决方案4】:

        我最初打算同意 Joseph Bui 的观点,理由是使用 POST 方法会提高处理器效率,Web 标准规定,如果请求不更改服务器上的数据,则应使用 GET 方法.

        与仅使用 POST 相比,加密数据的代码要多得多。

        【讨论】:

          【解决方案5】:

          这是上面 Brian 示例中的解密函数的一种奇特版本,如果您仅将其用于 QueryString,则可以使用它,因为它返回 NameValueCollection 而不是字符串。它还包含一个轻微的更正,因为 Brian 的示例将在没有

          的情况下中断
          stringToDecrypt = stringToDecrypt.Replace(" ", "+")
          

          如果要解密的字符串中有任何“空格”字符:

          Public Shared Function DecryptQueryString(ByVal stringToDecrypt As String, ByVal encryptionKey As String) As Collections.Specialized.NameValueCollection
              Dim inputByteArray(stringToDecrypt.Length) As Byte
              Try
                  Dim key() As Byte = System.Text.Encoding.UTF8.GetBytes(encryptionKey.Substring(0, encryptionKey.Length))
                  Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
                  Dim des As New DESCryptoServiceProvider()
                  stringToDecrypt = stringToDecrypt.Replace(" ", "+")
                  inputByteArray = Convert.FromBase64String(stringToDecrypt)
                  Dim ms As New MemoryStream()
                  Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), CryptoStreamMode.Write)
                  cs.Write(inputByteArray, 0, inputByteArray.Length)
                  cs.FlushFinalBlock()
                  Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
                  Dim decryptedString As String = encoding.GetString(ms.ToArray())
                  Dim nameVals() As String = decryptedString.Split(CChar("&"))
                  Dim queryString As New Collections.Specialized.NameValueCollection(nameVals.Length)
                  For Each nameValPair As String In nameVals
                      Dim pair() As String = nameValPair.Split(CChar("="))
                      queryString.Add(pair(0), pair(1))
                  Next
                  Return queryString
          
              Catch e As Exception
                  Throw New Exception(e.Message)
              End Try
          End Function
          

          我希望你觉得这很有用!

          【讨论】:

            【解决方案6】:

            你为什么要加密你的查询字符串?如果数据是敏感的,您应该使用 SSL。如果您担心有人偷看用户,请使用表单 POST 而不是 GET。

            我认为对于您的基本问题,很可能有比加密查询字符串更好的解决方案。

            【讨论】:

            • 我们也在使用 SSL,但是很久以前有人决定在查询字符串上传递这些数据,所以现在就是这样。
            • 如果你已经在使用SSL,你只关心肩冲浪,那么在参数值上使用Convert.ToBase64String(data)和Convert.FromBase64String(base64)怎么样。
            猜你喜欢
            • 2010-12-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多