none
Wrong size of decrypted data using AES RRS feed

  • Question

  • In our project we use follow methods to encrypt/decrypt important data before storing. Size of incoming bytes is always 32. Please take a look:

    public static string Encrypt(byte[] data, string pass)
    {
        using (var algorithm = new RijndaelManaged())
        {
            algorithm.Padding = PaddingMode.PKCS7;
    
            var salt = new byte[32];
            new Random().NextBytes(salt);
    
            using (var rng = new Rfc2898DeriveBytes(pass, salt, 3072))
            {
                algorithm.Key = rng.GetBytes(algorithm.KeySize / 8);
                algorithm.IV = rng.GetBytes(algorithm.BlockSize / 8);
    
                using (var oms = new MemoryStream())
                {
                    using (var ims = new MemoryStream(data))
                    {
                        var encryptor = algorithm.CreateEncryptor();
                        var cs = new CryptoStream(oms, encryptor, CryptoStreamMode.Write);
                        ims.CopyTo(cs);
                        cs.FlushFinalBlock();
                    }
    
                    oms.Flush();
    
                    var target = new byte[oms.Length + salt.Length];
                    oms.ToArray().CopyTo(target, 0);
                    salt.CopyTo(target, oms.Length);
    
                    return Convert.ToBase64String(target);
                }
            }
        }
    }
    
    
    public static byte[] Decrypt(string data, string pass)
    {
        var allbytes = Convert.FromBase64String(data);
    
        var salt = new byte[32];
        var databytes = new byte[allbytes.Length - salt.Length];
    
        Array.Copy(allbytes, databytes.Length, salt, 0, salt.Length);
        Array.Copy(allbytes, 0, databytes, 0, databytes.Length);
    
        using (var algorithm = new RijndaelManaged())
        {
            algorithm.Padding = PaddingMode.PKCS7;
    
            using (var rng = new Rfc2898DeriveBytes(pass, salt, 3072))
            {
                algorithm.Key = rng.GetBytes(algorithm.KeySize / 8);
                algorithm.IV = rng.GetBytes(algorithm.BlockSize / 8);
    
                using (var oms = new MemoryStream())
                {
                    using (var ims = new MemoryStream(databytes))
                    {
                        var decryptor = algorithm.CreateDecryptor();
                        using (var cs = new CryptoStream(ims, decryptor, CryptoStreamMode.Read))
                        {
                            cs.CopyTo(oms);
                        }
                    }
    
                    return oms.ToArray();
                }
            }
        }
    }

    This code works great in all cases. But on customer environment we've got 47 bytes instead of 32 during decryption. After some investigation I realized that such behavior may occurs when use incorrect passphrase (not same as encrypted but good enogth to decrypt in another byte combination). But customer very sure that password is correct. Might be a situation when environmental configuration (Windows of .Net updates, security config etc.) cause such problem? Thanks for any help.


    • Edited by DevForRest Monday, February 26, 2018 5:47 PM Fixed code mistake
    Monday, February 26, 2018 5:43 PM

All replies

  • Hi DevForRest,

    Thank you for posting here.

    >>But on customer environment we've got 47 bytes instead of 32 during decryption.

    The salt size must be 8 bytes or larger and the iteration count must be greater than zero. How do you get the salts of 47 bytes? The salt bytes is set to 32.  I test the code. There is no code to change this value of salts. 

    The code you provided works well with the same password. How do you get the bytes of data? And how do you convert the value you get from the decrypt to string? 

    If I test the code with wrong password, I will get the exception.

    Here is the way I invoke these two methods fro your reference.

       byte[] data = Encoding.UTF8.GetBytes("hello");
                string encrypt = Encrypt(data, "word");
                string str = Encoding.UTF8.GetString(Decrypt(encrypt, "word"));

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, March 8, 2018 1:49 AM
    Moderator
  • Thanks for reply.

    I use salt with 32 bytes length to encrypt and decrypt.

    Yes, code works well. But, as result of investigation, if use incorrect passphrase we can catch exception and also possible to decrypt data to wrong one - with incorrect bytes and size. 

    In my case more likely customer used incorrect passphrase to decrypt and got incorrect result.

    Please note, exception that you've got is only one of possible cases, other is - incorrect data without any exception.

    Thursday, March 15, 2018 4:53 PM