加密/解密

时间:2013-09-14 10:22:13

标签: c# encryption

我想解密已加密的文件,但收到错误“错误数据”。我认为我在这里使用生成密钥的方法在加密和解密时不生成相同的密钥。所以,我想宣布自己的密钥。我怎样才能做到这一点? 这是我的代码。

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

1 个答案:

答案 0 :(得分:0)

每次调用时,您的GenerateKey方法都会生成一个新的(随机)键(就像您在那里的评论中所述)。如果要使用随机密钥,请将生成的密钥存储在某处,并将其用于解密和加密。 您可以通过为加密/解密方法提供自己的字符串值来使用自己的“密码”进行加密。 e.g。

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.Key”中所看到的,DES支持长度为64位的密钥,因此请务必注意,该字符串必须包含8个字符。