المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : Invalid Padding when decrypting



C# Programming
08-18-2009, 09:01 PM
"Padding is invalid and cannot be removed" - this is the error message I am getting when trying to decrypt a file.

I have an application which will encrypt a file and then copy the file to a network ********. (No Problems)
The application can also 'download' the file and decrypt it - This is done by copying the file locally (with .tmp appended to the filename) and then decrypted to another file (so you basically end up with encrypted and decrypted files when you 'download').

If I upload a file, then I can download without problems. But I cannot download a file that another user has uploaded. Now, as I said you get two files when you download. If I use a testing application (which has exactly the same decryption code) then I can successfully decrypt the temporary file that was created during the 'download'

I cannot see the logic here at all. Please see my two methods below for encryption/decryption...

public static bool EncryptFile(string inputFile, string outputFile)
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(fileEncryptionPassword, new System.Security.Cryptography.SHA384Managed().ComputeHash(new System.Text.UnicodeEncoding().GetBytes(fileEncryptionPassword)));
byte[] key = pdb.GetBytes(32);
byte[] IV = pdb.GetBytes(16);

RijndaelManaged rm = new RijndaelManaged();
rm.Key = key;
rm.IV = IV;
rm.BlockSize = 128;
rm.Padding = PaddingMode.PKCS7;

FileStream fsIn = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(outputFile, FileMode.Create, FileAccess.Write);

bool success = true;

try{
CryptoStream cs = new CryptoStream(fsOut, rm.CreateEncryptor(), CryptoStreamMode.Write);

int bytesToWrite = 0;
byte[] buffer = new byte[4096];

while(true)
{
bytesToWrite = fsIn.Read(buffer, 0, buffer.Length);
if(bytesToWrite == 0)
break;
cs.Write(buffer, 0, bytesToWrite);
}

cs.Close();
}
catch
{
success = false;
}
fsIn.Close();
fsOut.Close();

if(!success)
File.Delete(outputFile);

return success;
}

public static bool DecryptFile(string inputFile, string outputFile)
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(fileEncryptionPassword, new System.Security.Cryptography.SHA384Managed().ComputeHash(new System.Text.UnicodeEncoding().GetBytes(fileEncryptionPassword)));
byte[] key = pdb.GetBytes(32);
byte[] IV = pdb.GetBytes(16);

RijndaelManaged rm = new RijndaelManaged();

rm.Key = key;
rm.IV = IV;
rm.BlockSize = 128;
rm.Padding = PaddingMode.PKCS7;

FileStream fsIn = new FileStream(inputFile, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(outputFile, FileMode.Create, FileAccess.Write);

bool success = true;

CryptoStream cs = new CryptoStream(fsIn, rm.CreateDecryptor(), CryptoStreamMode.Read);

try{
int bytesToWrite = 0;
byte[] buffer = new byte[4096];

while(true)
{
bytesToWrite = cs.Read(buffer, 0, buffer.Length);
if(bytesToWrite == 0)
break;
fsOut.Write(buffer, 0, bytesToWrite);
}
}
catch(Exception ex)
{
Debug.Show(ex.Message + "\n\n" + ex.StackTrace + "\n\n" + ex.InnerException.Message);
success = false;
}
finally{
cs.Close();
}

fsIn.Close();
fsOut.Close();

if(!success)
File.Delete(outputFile);

return success;
}

Sorry for so much code, but I'm sure it will be useful.

The decryption method is called directly after the code that copies the file from the network to a local folder, this is done using File.Copy() with the overwrite property set to true.

Thanks for any help

Life goes very fast. Tomorrow, today is already yesterday.