简体   繁体   中英

Encryption/ Decryption

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM