11

I am using the following code to Encrypt/Decrypt a querystring and pass it from one page to another. The resulting output is missing a '+' (see at the bottom of the question). What can I do to make sure the '+' comes thru as I am already using urlencode/urldecode?

//Encryption page

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

Decryption page (I use this page to print out what I the decrypted string from the first page and then compare it what I get in the 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==");            

    }

The end result is the following two lines (the first line is the output from the URL). They almost match except the first URL (the encoded/decoded querystring result) is missing the '+' symbol. Any idea how to avoid this?

AUwsHc8j/llULnuwVnspNwolBUAhl5GFqC6iOrUN5euZFrOgFVypqTGfhAaooLxa0Fko 9KGtRh3UcQJtzkfSw==

AUwsHc8j/llULnuwVnspNwolBUAhl5GFqC6iOrUN5euZFrOgFVypqTGfhAaooLxa0Fko+9KGtRh3UcQJtzkfSw==

Dkong
  • 2,748
  • 10
  • 54
  • 73
  • Added some sample code. – Dkong Feb 19 '15 at 19:10
  • Check this answer concerning passing base64-encoded strings in query strings: http://stackoverflow.com/questions/1374753/passing-base64-encoded-strings-in-url – Jim Flood Feb 19 '15 at 19:13
  • 1
    By the by, `AesCryptoServiceProvider` implements the `IDisposable` interface, so its usage should also be wrapped in a `using` block for proper deterministic disposal of resources. – Jesse C. Slicer Feb 19 '15 at 19:17
  • @JimFlood You could use the "share" button and point to the correct answer (the one with the most upvotes - not the accepted one in this case) instead of the question. Just a hint... – Maarten Bodewes Feb 19 '15 at 19:57
  • @MaartenBodewes you got the wrong guy. I think you mean to reply to Jim Flood. – Jesse C. Slicer Feb 19 '15 at 19:59
  • @JimFlood: I would recommend replacing the + and / characters to get the base64url character set; with ciphertext you don't know how many escapes are going to be generated. Dkong: this has probably something to do with HTTP/HTML encoding. You should not use strings as keys and you should not use `TransformFinalBlock`, and you should use a random IV (and prefix it to the ciphertext) and add an authentication tag to be secure. – Maarten Bodewes Feb 19 '15 at 20:03
  • @MaartenBodewes Right, I agree. I wasn't suggesting not using base64. I could have pointed to the better answer (the one you refer to) had I thought of the share link. ;-) – Jim Flood Feb 19 '15 at 23:04
  • @MaartenBodewes what would you recommend I replace + and / characters with? Can you please elaborate on why I should not use TransformFinalBlock? I am new to cryptography. I have read about generating a random IV, but the problem is I am passing the encryption string from one .NET app to a separate .NET app, so how would I get them to both have the same random IV? Also not sure about the reason of why to prefix the ciphertext with the random IV? – Dkong Feb 20 '15 at 18:45

1 Answers1

5

ok fixed it, simply removed the urldecode method. The decode appears to happen automatically.

Dkong
  • 2,748
  • 10
  • 54
  • 73