C#加密解密文件.docx
《C#加密解密文件.docx》由会员分享,可在线阅读,更多相关《C#加密解密文件.docx(11页珍藏版)》请在冰豆网上搜索。
C#加密解密文件
C#加密解密文件
C#加密解密文件[转]2008年06月26日星期四15:
57
加密文件
要加密文件,请按照下列步骤操作:
1.启动VisualStudio2005或VisualStudio.NET。
2.单击“项目”下的“VisualC#”,然后单击“模板”下的“控制台应用程序”。
VisualC#.NET为您创建一个静态类,以及一个空的Main()过
程。
3.对以下命名空间使用using语句(如以下示例代码中所示):
•System
•System.Security
•System.Security.Cryptography
•System.Text
•System.IO
这样,在后面的代码中就不必从这些命名空间中限定声明了。
这些语句必须位于任何其他声明之前。
usingSystem;
usingSystem.IO;
usingSystem.Security;
usingSystem.Security.Cryptography;
usingSystem.Runtime.InteropServices;
usingSystem.Text;
4.生成密钥以加密和解密数据。
DESCryptoServiceProvider基于一种对称加密算法。
对称加密需要密钥和初始化矢量(IV)来加密数据。
要解密该数
据,您必须拥有此同一密钥和IV。
您还必须使用相同的加密算法。
您可以使用下列方法之一生成密钥:
•方法1您可以提示用户输入密码。
然后,
将此密码用作密钥和IV。
•方法2当您创建对称加密类的新实例时,将为会话自动创建一个新的密钥和IV。
使用由受管理的对称加密类生成的密钥和IV来加密和解密文件。
5.添加以下函数为会话生成一个新的密钥(按照步骤4的方法2中的说明):
//Callthisfunctiontoremovethekeyfrommemoryafteruse
forsecurity.
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL",EntryPoint="RtlZeroMemory")]
publicstaticexternboolZeroMemory(refstringDestination,intLength);//FunctiontoGeneratea64bitsKey.
staticstringGenerateKey()
{
//CreateaninstanceofSymetricAlgorithm.KeyandIVisgeneratedautomatically.
DESCryptoServiceProviderdesCrypto=(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
//UsetheAutomaticallygeneratedkeyforEncryption.
returnASCIIEncoding.ASCII.GetString(desCrypto.Key);
}
6.在您的类中创建一个命名为EncryptFile的方法。
EncryptFile类必须具有以下3个参数:
•sInputFilename
•sOutputFilename
•sKey(用于加密和解密文件的密钥。
)
staticvoidEncryptFile(stringsInputFilename,
stringsOutputFilename,
stringsKey)
7.在EncryptFile过程中,创建一个输入FileStream对象和一个输出FileStream对象。
这些对象可以从目标文件中读取和向其中写入。
FileStreamfsInput=newFileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
FileStreamfsEncrypted=newFileStream(sOutputFilename,
FileMode.Create,
FileAccess.Write);
8.声明一个DESCryptoServiceProvider类的实例。
这表示对文件使用的实际加密和解密技术。
此时,如果您更喜欢使用RSAsecutiry或另一种加密
技术,则可以创建一个不同的提供程序。
DESCryptoServiceProviderDES=newDESCryptoServiceProvider();
9.必须以字节数组的形式给加密提供程序提供密钥。
System.Text命名空间提供了一个名为GetBytes()的函数。
GetBytes()函数的编码特征之一是
,它取一个字符串,然后返回一个字节数组。
各种加密技术采用的密钥长度是不相同的。
例如,数据加密标准(DES)使用等于8个字节或8个字符
的64位密钥。
如果您不提供密钥,提供程序就会随机生成一个密钥。
这将成功地加密文件,但是无法解密文件。
请注意,您还必须提供初始化矢量(IV)。
该值用作
加密的一部分。
与密钥相似,如果您未提供IV,提供程序就会随机生成一个。
由于该值对于加密和解密必须相同,所以不能让提供程序随机生成这些
值。
DES.Key=ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV=ASCIIEncoding.ASCII.GetBytes(sKey);
10.创建一个CryptoStream类的实例,方法是:
使用加密提供程序获得一个加密对象(CreateEncryptor),并将现有的输出FileStream对象作为
构造函数的一部分。
ICryptoTransformdesencrypt=DES.CreateEncryptor();
CryptoStreamcryptostream=newCryptoStream(fsEncrypted,
desencrypt,
CryptoStreamMode.Write);
11.读入输入文件,然后写出到输出文件。
传递CryptoStream对象,文件将使用您提供的密钥加密。
byte[]bytearrayinput=newbyte
[fsInput.Length-1];
fsInput.Read(bytearrayinput,0,bytearrayinput.Length);
cryptostream.Write(bytearrayinput,0,bytearrayinput.Length);
解密文件
要解密文件,请按照下列步骤操作:
1.创建一个方法,然后将它命名为DecryptFile。
解密过程与加密过程相似,但DecryptFile过程与EncryptFile过程有两个关键区别。
•
CryptoStream对象是使用CreateDecryptor而非CreateEncryptor创建的,这将指定对象的使用方式。
•在将解密的文本写入到目标文件时,CryptoStream对象现在是源,而不是目标流。
staticvoidDecryptFile(stringsInputFilename,
stringsOutputFilename,
stringsKey)
{
DESCryptoServiceProviderDES=newDESCryptoServiceProvider();
//A64bitkeyandIVisrequiredforthisprovider.
//SetsecretkeyForDESalgorithm.
DES.Key=ASCIIEncoding.ASCII.GetBytes(sKey);
//Setinitializationvector.
DES.IV=ASCIIEncoding.ASCII.GetBytes(sKey);
//Createafilestreamtoreadtheencryptedfileback.
FileStreamfsread=newFileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
//CreateaDESdecryptorfromtheDESinstance.
ICryptoTransformdesdecrypt=DES.CreateDecryptor();
//Createcryptostreamsettoreadanddoa
//DESdecryptiontransformonincomingbytes.
CryptoStreamcryptostreamDecr=newCryptoStream(fsread,
desdecrypt,
CryptoStreamMode.Read);
//Printthecontentsofthedecryptedfile.
StreamWriterfsDecrypted=newStreamWriter(sOutputFilename);
fsDecrypted.Write(newStreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
2.将以下几行添加到Main()过程,以调用EncryptFile和DecryptFile:
staticvoidMain()
{
//Mustbe64bits,8bytes.
//Distributethiskeytotheuserwhowilldecryptthisfile.
stringsSecretKey;
//Getthekeyforthefiletoencrypt.
sSecretKey=GenerateKey();
//Foradditionalsecuritypinthekey.
GCHandlegch=GCHandle.Alloc(sSecretKey,GCHandleType.Pinned);
//Encryptthefile.
EncryptFile(@"C:
\MyData.txt",
@"C:
\Encrypted.txt",
sSecretKey);
//Decryptthefile.
DecryptFile(@"C:
\Encrypted.txt",
@"C:
\Decrypted.txt",
sSecretKey);
//Removethekeyfrommemory.
ZeroMemory(gch.AddrOfPinnedObject(),sSecretKey.Length*2);
gch.Free();
}
3.保存文件。
运行您的应用程序。
确保输入文件名使用的路径指向一个现有文件。
测试过程
用一个文本文件(.txt)测试此代码,确认它可对此文件进行正确的加密和解密。
确保将文件解密到一个新文件(如本文中的Main()过程中所示),
而不是解密到原来的文件中。
检查解密后的文件,然后与原文件进行比较。
完整代码列表
usingSystem;
usingSystem.IO;
usingSystem.Security;
usingSystem.Security.Cryptography;
usingSystem.Runtime.InteropServices;
usingSystem.Text;
namespaceCSEncryptDecrypt
{
classClass1
{
//Callthisfunctiontoremovethekeyfrommemoryafteruseforsecurity
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL",EntryPoint="RtlZeroMemory")]
publicstaticexternboolZeroMemory(IntPtrDestination,intLength);//FunctiontoGeneratea64bitsKey.
staticstringGenerateKey()
{
//CreateaninstanceofSymetricAlgorithm.KeyandIVisgeneratedautomatically.
DESCryptoServiceProviderdesCrypto=(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
//UsetheAutomaticallygeneratedkeyforEncryption.
returnASCIIEncoding.ASCII.GetString(desCrypto.Key);
}
staticvoidEncryptFile(stringsInputFilename,
stringsOutputFilename,
stringsKey)
{
FileStreamfsInput=newFileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
FileStreamfsEncrypted=newFileStream(sOutputFilename,
FileMode.Create,
FileAccess.Write);
DESCryptoServiceProviderDES=newDESCryptoServiceProvider();
DES.Key=ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV=ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransformdesencrypt=DES.CreateEncryptor();
CryptoStreamcryptostream=newCryptoStream(fsEncrypted,
desencrypt,
CryptoStreamMode.Write);
byte[]bytearrayinput=newbyte[fsInput.Length];
fsInput.Read(bytearrayinput,0,bytearrayinput.Length);
cryptostream.Write(bytearrayinput,0,bytearrayinput.Length);
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}
staticvoidDecryptFile(stringsInputFilename,
stringsOutputFilename,
stringsKey)
{
DESCryptoServiceProviderDES=newDESCryptoServiceProvider();
//A64bitkeyandIVisrequiredforthisprovider.
//SetsecretkeyForDESalgorithm.
DES.Key=ASCIIEncoding.ASCII.GetBytes(sKey);
//Setinitializationvector.
DES.IV=ASCIIEncoding.ASCII.GetBytes(sKey);
//Createafilestreamtoreadtheencryptedfileback.
FileStreamfsread=newFileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
//CreateaDESdecryptorfromtheDESinstance.
ICryptoTransformdesdecrypt=DES.CreateDecryptor();
//Createcryptostreamsettoreadanddoa
//DESdecryptiontransformonincomingbytes.
CryptoStreamcryptostreamDecr=newCryptoStream(fsread,
desdecrypt,
CryptoStreamMode.Read);
//Printthecontentsofthedecryptedfile.
StreamWriterfsDecrypted=newStreamWriter(sOutputFilename);
fsDecrypted.Write(newStreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
staticvoidMain()
{
//Mustbe64bits,8bytes.
//Distributethiskeytotheuserwhowilldecryptthisfile.
stringsSecretKey;
//GettheKeyforthefiletoEncrypt.
sSecretKey=GenerateKey();
//ForadditionalsecurityPinthekey.
GCHandlegch=GCHandle.Alloc(sSecretKey,GCHandleType.Pinned);
//Encryptthefile.
EncryptFile(@"C:
\MyData.txt",
@"C:
\Encrypted.txt",
sSecretKey);
//Decryptthefile.
DecryptFile(@"C:
\Encrypted.txt",
@"C:
\Decrypted.txt",
sSecretKey);
//RemovetheKeyfrommemory.
ZeroMemory(gch.AddrOfPinnedObject(),sSecretKey.Length*2);
gch.Free();
}
}
}