I want to decrypt an already encrypted file but getting the error "Bad Data". I think that that the method I used here to generate key is not generating same key while encrypting and decrypting. So, I want to declare my own key. How can i do this? This is my code.
using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
public static class crypto
{
public static String tempdir = Environment.ExpandEnvironmentVariables("%temp%");
// Call this function to remove the key from memory after use for security
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
public static extern bool ZeroMemory(IntPtr Destination, int Length);
// Function to Generate a 64 bits Key.
static string GenerateKey()
{
// Create an instance of Symetric Algorithm. Key and IV is generated automatically.
DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
Clipboard.SetText(desCrypto.Key.ToString());
// Use the Automatically generated key for Encryption.
return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
}
static void EncryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
{
FileStream fsInput = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
FileStream fsEncrypted = new FileStream(sOutputFilename,
FileMode.Create,
FileAccess.Write);
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream = new CryptoStream(fsEncrypted,
desencrypt,
CryptoStreamMode.Write);
byte[] bytearrayinput = new byte[fsInput.Length];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}
static void DecryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
//A 64 bit key and IV is required for this provider.
//Set secret key For DES algorithm.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
//Set initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
//Create a file stream to read the encrypted file back.
FileStream fsread = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
//Create a DES decryptor from the DES instance.
ICryptoTransform desdecrypt = DES.CreateDecryptor();
//Create crypto stream set to read and do a
//DES decryption transform on incoming bytes.
CryptoStream cryptostreamDecr = new CryptoStream(fsread,
desdecrypt,
CryptoStreamMode.Read);
//Print the contents of the decrypted file.
StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
public static void Encrypt(String table, String file)
{
GenerateKey();
try
{
String filepath = Path.Combine(tempdir + @"\Manager\data\" + table,file);
// Must be 64 bits, 8 bytes.
// Distribute this key to the user who will decrypt this file.
string sSecretKey;
// Get the Key for the file to Encrypt.
sSecretKey = GenerateKey();
// For additional security Pin the key.
GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned);
// Encrypt the file.
EncryptFile(@"" + filepath,
@"" + Application.StartupPath + @"\data\"+ table + @"\" + file,
sSecretKey);
try
{
File.Delete(filepath);
}
catch (Exception ex1)
{
MessageBox.Show(ex1.Message, "Error while deletion of decrypted file");
}
// Remove the Key from memory.
ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
gch.Free();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error during encryption");
}
}
public static void Decrypt(String table, String file)
{
try
{
String filepath = Path.Combine(tempdir + @"\Manager\data\"+table, file);
create.folder("Manager", tempdir);
create.folder(table, tempdir + @"\Manager\");
create.file(file, tempdir + @"\Manager\" + table);
// Must be 64 bits, 8 bytes.
// Distribute this key to the user who will decrypt this file.
string sSecretKey;
// Get the Key for the file to Encrypt.
sSecretKey = GenerateKey();
// For additional security Pin the key.
GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned);
// Decrypt the file.
DecryptFile(@".\data\" + table + @"\" + file,
@"" + filepath,
sSecretKey);
// Remove the Key from memory.
ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
gch.Free();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error during decryption");
}
}
}
Your GenerateKey Method generates a new (random) key every time you call it (like you already stated in the comments there). If you want to use a random key, store the generated key somewhere and use it for decryption and encryption. You can use a own "password" for encryption by giving your encryption/decryption method a own string value. eg
crypto.EncryptFile(@"D:\Testing\brownfox.txt", @"D:\Testing\brownfox_enc.txt", "abcd1234");
crypto.DecryptFile(@"D:\Testing\brownfox_enc.txt", @"D:\Testing\brownfox_dec.txt", "abcd1234");
As you can see in the MSDN reference to "DES.Key", DES supports keys with a length of 64bit, so it's important to note, that the string must have 8 characters.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.