加密/解密

本文关键字:解密 加密 | 更新日期: 2023-09-27 18:31:21

我想解密一个已经加密的文件,但收到错误"坏数据"。我认为我在这里用来生成密钥的方法在加密和解密时不会生成相同的密钥。所以,我想声明我自己的密钥。我该怎么做?这是我的代码。

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

加密/解密

每次调用 GenerateKey 方法时都会生成一个新的(随机)密钥(就像您在注释中已经说明的那样)。如果要使用随机密钥,请将生成的密钥存储在某个位置,并将其用于解密和加密。您可以通过为加密/解密方法提供自己的字符串值来使用自己的"密码"进行加密。例如

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

正如您在 MSDN 对"DES.密钥",DES 支持长度为 64 位的密钥,因此请务必注意,字符串必须包含 8 个字符。