0

In my project there is a section which makes decryption using one among several cryptography providers such as DESCryptoServiceProvider, TripleDESCryptoServiceProvider, RijndaelManaged etc.

Project was running without any issue with TripleDESCryptoServiceProvider, but after Fortify suggests to use RijndaelManaged, system starts to throw Length of the data to decrypt is invalid.

This was the story in short. I'm not a professional on cryptography things, but if I'm not wrong, the problem should be related with the way I'm creating my byte[]. Now here comes the codes:

This is the part where is set methodology:

public System.Security.Cryptography.SymmetricAlgorithm _crypto;

public void Symmetric(MyProject.Framework.Security.Symmetric.Provider provider)
    {
        switch (provider)
        {
            case MyProject.Framework.Security.Symmetric.Provider.DES:
                this._crypto = new System.Security.Cryptography.DESCryptoServiceProvider();
                break;
            case MyProject.Framework.Security.Symmetric.Provider.RC2:
                this._crypto = new System.Security.Cryptography.RC2CryptoServiceProvider();
                break;
            case MyProject.Framework.Security.Symmetric.Provider.Rijndael:
                this._crypto = new System.Security.Cryptography.RijndaelManaged();
                break;
            case MyProject.Framework.Security.Symmetric.Provider.TripleDES:
                this._crypto = new System.Security.Cryptography.TripleDESCryptoServiceProvider();
                break;
        }
    }

And this is the method which generates the byte array:

    public byte[] FromHex(string hexEncoded)
    {
        if (hexEncoded == null || hexEncoded.Length == 0)
        {
            return null;
        }

        checked
        {
            byte[] result;

            try
            {
                int num = Convert.ToInt32((double)hexEncoded.Length / 2.0);

                byte[] array = new byte[num - 1 + 1];

                int arg_36_0 = 0;

                int num2 = num - 1;

                for (int i = arg_36_0; i <= num2; i++)
                {
                    array[i] = Convert.ToByte(hexEncoded.Substring(i * 2, 2), 16);
                }

                result = array;
            }
            catch (Exception expr_5A)
            {
                throw new FormatException("The provided string does not appear to be Hex encoded", expr_5A);
            }

            return result;
        }
    }

Below is my Decrypt method,

    public void Decrypt(byte[] encryptedData)
    {
        System.IO.MemoryStream stream = new System.IO.MemoryStream(encryptedData, 0, encryptedData.Length);

        checked
        {
            byte[] array = new byte[encryptedData.Length - 1 + 1];

            using (System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(stream, this._crypto.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Read))
            {
                try
                {
                    cryptoStream.Read(array, 0, encryptedData.Length - 1);
                }
                catch (System.Security.Cryptography.CryptographicException expr_56)
                {
                    throw new System.Security.Cryptography.CryptographicException("Unable to decrypt data. The provided key may be invalid.", expr_56);
                }
                finally
                {
                    cryptoStream.Close();
                }
            }
        }
    }

When I call Decrypt method,

        var provider = MyProject.Framework.Security.Symmetric.Provider.Rijndael;

        instance.Symmetric(provider);

        var openString = "C9B7163BFA3E5E46";

        var byteArray = instance.FromHex(openString);

        instance.Decrypt(byteArray);

It throws Length of the data to decrypt is invalid on that cryptoStream.Read(...) as described on above.

Could someone advice me with the correct way of handling these? Is it really the way I'm creating that byte array which I send to my Decrypt method?

Thanks in advance.

RaZzLe
  • 1,984
  • 3
  • 13
  • 24
  • `encryptedData.Length - 1` why `-1`? – shingo Jun 28 '22 at 07:40
  • Which .NET version are you running? – Topaco Jun 28 '22 at 08:24
  • It is .NET 4.7.2 – RaZzLe Jun 28 '22 at 08:26
  • 1
    I can't reproduce this. However, you didn't actually post an MCVE, so I had to implement my own test case, which may not cover your issue. Therefore, post an MCVE so that the problem is reproducible. Note that decryption will of course fail if encryption and decryption use different `_crypto` instances and the randomly generated keys and IV are used. – Topaco Jun 28 '22 at 08:50
  • Thank you for your points Topaco. I will check and come back as soon as possible – RaZzLe Jun 28 '22 at 09:00
  • Note that your implementation writes the plaintext into an array that has the size of the ciphertext, which is larger than the plaintext because of the padding. (probably that's why `encryptedData.Length - 1` is no problem, see 1st comment). `read()` returns the number of bytes read, so the remaining part could be removed in principle. But probably it's more convenient to stick to the MS pattern, s. e.g. [here](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-6.0). – Topaco Jun 28 '22 at 09:20

0 Answers0