Length of the data to decrypt is invalid

Discussion in 'ASP .Net' started by Hannibal111111, Jun 27, 2006.

  1. I found this code on a site for doing string encryption/decryption.
    The string will encrypt fine, but I get this error when I try to
    decrypt. Any idea why? I posted the code below.

    The error actually points to this line of code in byte[] decrypt
    function:

    cs.FlushFinalBlock();

    public static byte[] encrypt(byte[] clearData, byte[] Key, byte[] IV)
    {
    // Create a MemoryStream to accept the encrypted bytes
    MemoryStream ms = new MemoryStream();

    // Create a symmetric algorithm.
    // We are going to use Rijndael because it is strong and
    // available on all platforms.
    // You can use other algorithms, to do so substitute the
    // next line with something like
    // TripleDES alg = TripleDES.Create();
    Rijndael alg = Rijndael.Create();

    // Now set the key and the IV.
    // We need the IV (Initialization Vector) because
    // the algorithm is operating in its default
    // mode called CBC (Cipher Block Chaining).
    // The IV is XORed with the first block (8 byte)
    // of the data before it is encrypted, and then each
    // encrypted block is XORed with the
    // following block of plaintext.
    // This is done to make encryption more secure.

    // There is also a mode called ECB which does not need an IV,
    // but it is much less secure.
    alg.Key = Key;
    alg.IV = IV;

    // Create a CryptoStream through which we are going to be
    // pumping our data.
    // CryptoStreamMode.Write means that we are going to be
    // writing data to the stream and the output will be written
    // in the MemoryStream we have provided.
    CryptoStream cs = new CryptoStream(ms,
    alg.CreateEncryptor(), CryptoStreamMode.Write);

    // Write the data and make it do the encryption
    cs.Write(clearData, 0, clearData.Length);

    // Close the crypto stream (or do FlushFinalBlock).
    // This will tell it that we have done our encryption and
    // there is no more data coming in,
    // and it is now a good time to apply the padding and
    // finalize the encryption process.
    cs.Close();

    // Now get the encrypted data from the MemoryStream.
    // Some people make a mistake of using GetBuffer() here,
    // which is not the right way.
    byte[] encryptedData = ms.ToArray();

    return encryptedData;
    }

    /// <summary>
    /// Encrypt a string into a string using a password
    /// </summary>
    /// <param name="clearText"></param>
    /// <param name="Password"></param>
    /// <returns></returns>
    public static string encrypt(string clearText, string Password)
    {
    // First we need to turn the input string into a byte array.
    byte[] clearBytes =
    System.Text.Encoding.Unicode.GetBytes(clearText);

    // Then, we need to turn the password into Key and IV
    // We are using salt to make it harder to guess our key
    // using a dictionary attack -
    // trying to guess a password by enumerating all possible words.
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
    0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

    // Now get the key/IV and do the encryption using the
    // function that accepts byte arrays.
    // Using PasswordDeriveBytes object we are first getting
    // 32 bytes for the Key
    // (the default Rijndael key length is 256bit = 32bytes)
    // and then 16 bytes for the IV.
    // IV should always be the block size, which is by default
    // 16 bytes (128 bit) for Rijndael.
    // If you are using DES/TripleDES/RC2 the block size is
    // 8 bytes and so should be the IV size.
    // You can also read KeySize/BlockSize properties off
    // the algorithm to find out the sizes.
    byte[] encryptedData = encrypt(clearBytes,
    pdb.GetBytes(32), pdb.GetBytes(16));

    // Now we need to turn the resulting byte array into a string.
    // A common mistake would be to use an Encoding class for that.
    //It does not work because not all byte values can be
    // represented by characters.
    // We are going to be using Base64 encoding that is designed
    //exactly for what we are trying to do.
    return Convert.ToBase64String(encryptedData);
    }

    /// <summary>
    /// // Decrypt a byte array into a byte array using a key and an IV
    /// </summary>
    /// <param name="cipherData"></param>
    /// <param name="Key"></param>
    /// <param name="IV"></param>
    /// <returns></returns>
    public static byte[] decrypt(byte[] cipherData,
    byte[] Key, byte[] IV)
    {
    // Create a MemoryStream that is going to accept the
    // decrypted bytes
    MemoryStream ms = new MemoryStream();

    // Create a symmetric algorithm.
    // We are going to use Rijndael because it is strong and
    // available on all platforms.
    // You can use other algorithms, to do so substitute the next
    // line with something like
    // TripleDES alg = TripleDES.Create();
    Rijndael alg = Rijndael.Create();

    // Now set the key and the IV.
    // We need the IV (Initialization Vector) because the algorithm
    // is operating in its default
    // mode called CBC (Cipher Block Chaining). The IV is XORed with
    // the first block (8 byte)
    // of the data after it is decrypted, and then each decrypted
    // block is XORed with the previous
    // cipher block. This is done to make encryption more secure.
    // There is also a mode called ECB which does not need an IV,
    // but it is much less secure.
    alg.Key = Key;
    alg.IV = IV;

    // Create a CryptoStream through which we are going to be
    // pumping our data.
    // CryptoStreamMode.Write means that we are going to be
    // writing data to the stream
    // and the output will be written in the MemoryStream
    // we have provided.
    CryptoStream cs = new CryptoStream(ms,
    alg.CreateDecryptor(), CryptoStreamMode.Write);

    // Write the data and make it do the decryption
    cs.Write(cipherData, 0, cipherData.Length);

    // Close the crypto stream (or do FlushFinalBlock).
    // This will tell it that we have done our decryption
    // and there is no more data coming in,
    // and it is now a good time to remove the padding
    // and finalize the decryption process.
    //cs.Close();
    cs.FlushFinalBlock();

    // Now get the decrypted data from the MemoryStream.
    // Some people make a mistake of using GetBuffer() here,
    // which is not the right way.
    byte[] decryptedData = ms.ToArray();

    return decryptedData;
    }

    /// <summary>
    /// Decrypt a string into a string using a password
    /// </summary>
    /// <param name="cipherText"></param>
    /// <param name="Password"></param>
    /// <returns></returns>
    public static string decrypt(string cipherText, string Password)
    {
    // First we need to turn the input string into a byte array.
    // We presume that Base64 encoding was used
    byte[] cipherBytes = Convert.FromBase64String(cipherText);

    // Then, we need to turn the password into Key and IV
    // We are using salt to make it harder to guess our key
    // using a dictionary attack -
    // trying to guess a password by enumerating all possible words.
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65,
    0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

    // Now get the key/IV and do the decryption using
    // the function that accepts byte arrays.
    // Using PasswordDeriveBytes object we are first
    // getting 32 bytes for the Key
    // (the default Rijndael key length is 256bit = 32bytes)
    // and then 16 bytes for the IV.
    // IV should always be the block size, which is by
    // default 16 bytes (128 bit) for Rijndael.
    // If you are using DES/TripleDES/RC2 the block size is
    // 8 bytes and so should be the IV size.
    // You can also read KeySize/BlockSize properties off
    // the algorithm to find out the sizes.
    byte[] decryptedData = decrypt(cipherBytes,
    pdb.GetBytes(32), pdb.GetBytes(16));

    // Now we need to turn the resulting byte array into a string.
    // A common mistake would be to use an Encoding class for that.
    // It does not work
    // because not all byte values can be represented by characters.
    // We are going to be using Base64 encoding that is
    // designed exactly for what we are trying to do.
    return System.Text.Encoding.Unicode.GetString(decryptedData);
    }
     
    Hannibal111111, Jun 27, 2006
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. hivie

    Length of data to decrypt is invalid Rijndael

    hivie, Jun 13, 2005, in forum: ASP .Net Security
    Replies:
    2
    Views:
    527
    Duane Laflotte
    Jun 13, 2005
  2. steve baker
    Replies:
    0
    Views:
    305
    steve baker
    Aug 3, 2005
  3. Bishoy George

    Length of the data to decrypt is invalid

    Bishoy George, Apr 5, 2006, in forum: ASP .Net Security
    Replies:
    4
    Views:
    632
    Bishoy George
    Apr 7, 2006
  4. Barb
    Replies:
    0
    Views:
    504
  5. Replies:
    1
    Views:
    435
    Daniel Martin
    Jun 16, 2007
Loading...

Share This Page