Length of the data to decrypt is invalid



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

.



Relevant Pages

  • Re: Byte array to string and back - newbie question
    ... // Create a symmetric algorithm. ... This is done to make encryption more ... // Encrypt a string into a string using a password ... // Decrypt a byte array into a byte array using a key and an IV ...
    (microsoft.public.dotnet.framework.aspnet.security)
  • Re: How good an encryption algorithm is this?
    ... As long as the string can be converted to/from a byte stream, ... then you can apply that after the encryption. ... > So I decided to invent my own algorithm, and I just wanted anybody's> opinion on how secure this could be compared to the Win32 API version. ... > HCRYPTHASH hCryptHash; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: How good an encryption algorithm is this?
    ... As long as the string can be converted to/from a byte stream, ... then you can apply that after the encryption. ... > So I decided to invent my own algorithm, and I just wanted anybody's> opinion on how secure this could be compared to the Win32 API version. ... > HCRYPTHASH hCryptHash; ...
    (microsoft.public.vc.language)
  • Re: cryptography
    ... The Rijndael class is intended to be the ... > For a couple examples of simple encryption using the RijndaelManaged class ... >> internal static void Encrypt(string StringToCrypt, string fileOut, string ... >> when i run the above code, encryption is smooth,however when decryption ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: CREATE SYMMETRIC KEY
    ... To test it out using encryption, I created a database, TestEncrypt, using ... CREATE SYMMETRIC KEY SSN_Key_01 ... Either no algorithm has been specified or the bitlength and the algorithm ... DECRYPTION BY CERTIFICATE HumanResources037; ...
    (microsoft.public.sqlserver.security)