[英]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). 您的GenerateKey方法每次调用时都会生成一个新的(随机)密钥(就像您已经在其中的注释中所述)。 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. 正如您在MSDN中对“ DES.Key”的引用中所看到的那样,DES支持长度为64位的密钥,因此必须注意,字符串必须包含8个字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.