使用AES 256加密和解密查询字符串值

11
我正在使用以下代码对查询字符串进行加密/解密,并将其从一个页面传递到另一个页面。结果输出中缺少一个'+'(请参见问题底部)。我该怎么做才能确保'+'符号正常显示,因为我已经在使用urlencode / urldecode了吗?
    protected void Page_Load(object sender, EventArgs e)
    {
        string text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";            
        Response.Write("256:" + Decrypt256(Encrypt256(text)));
        Response.Write(string.Format("<br/><a href=\"decrypt.aspx?p={0}\">{0}</a>", HttpUtility.UrlEncode(Encrypt256(text))));            
    }


    private const string AesIV256 = @"!QAZ2WSX#EDC4RFV";
    private const string AesKey256 = @"5TGB&YHN7UJM(IK<5TGB&YHN7UJM(IK<";


    private string Encrypt256(string text)
    {            
        // AesCryptoServiceProvider
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();            
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.IV = Encoding.UTF8.GetBytes(AesIV256);
        aes.Key = Encoding.UTF8.GetBytes(AesKey256);
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        // Convert string to byte array
        byte[] src = Encoding.Unicode.GetBytes(text);

        // encryption
        using (ICryptoTransform encrypt = aes.CreateEncryptor())
        {
            byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);

            // Convert byte array to Base64 strings
            return Convert.ToBase64String(dest);
        }
    }

    /// <summary>
    /// AES decryption
    /// </summary>
    private string Decrypt256(string text)
    {            
        // AesCryptoServiceProvider
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.IV = Encoding.UTF8.GetBytes(AesIV256);
        aes.Key = Encoding.UTF8.GetBytes(AesKey256);
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        // Convert Base64 strings to byte array
        byte[] src = System.Convert.FromBase64String(text);

        // decryption
        using (ICryptoTransform decrypt = aes.CreateDecryptor())
        {
            byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
            return Encoding.Unicode.GetString(dest);
        }
    }

解密页面(我使用此页面将第一页解密的字符串打印出来,然后与URL中得到的内容进行比较):

     protected void Page_Load(object sender, EventArgs e)
    {
        string urlValue = HttpUtility.UrlDecode(Request.QueryString["p"].Trim());
     Decrypt256(Encoding.ASCII.GetString(s2));            

        Response.Write(urlValue + "<br /><br />");     
        Response.Write("AUwsHc8j/llULnuwVnspNwolBUAhl5GFqC6iOrUN5euZFrOgFVypqTGfhAaooLxa0Fko+9KGtRh3UcQJtzkfSw==");            

    }
下面是两行结果(第一行是URL输出结果)。它们几乎匹配,除了第一个URL(已编码/解码的查询字符串结果)缺少“+”符号。有什么想法可以避免这种情况吗?AUwsHc8j/llULnuwVnspNwolBUAhl5GFqC6iOrUN5euZFrOgFVypqTGfhAaooLxa0Fko9KGtRh3UcQJtzkfSw==AUwsHc8j/llULnuwVnspNwolBUAhl5GFqC6iOrUN5euZFrOgFVypqTGfhAaooLxa0Fko+9KGtRh3UcQJtzkfSw==

添加了一些示例代码。 - Dkong
请查看以下关于在查询字符串中传递base64编码字符串的答案:https://dev59.com/FnM_5IYBdhLWcg3wcSx_ - Jim Flood
1
顺便提一下,AesCryptoServiceProvider 实现了 IDisposable 接口,因此它的使用也应该被包装在一个 using 块中,以便正确地确定性地处理资源。 - Jesse C. Slicer
@JimFlood 你可以使用“分享”按钮并指向正确的答案(在这种情况下,是最多赞同的答案而不是被接受的答案),而不是问题。只是一个提示... - Maarten Bodewes
@MaartenBodewes您建议我替换+和/字符,有什么好的推荐吗?能否详细说明一下为什么不应使用TransformFinalBlock?我对加密学新手。我已经了解了生成随机IV的方法,但问题是我正在将加密字符串从一个.NET应用程序传递到另一个.NET应用程序,那么如何使它们都具有相同的随机IV呢?同时,不确定在密文前缀处添加随机IV的原因是什么? - Dkong
显示剩余3条评论
1个回答

5

好的,已经解决了,只需删除urldecode方法即可。解码似乎会自动发生。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接