如何加密和解密文件,通过使用 Visual C#

文章翻译 文章翻译
文章编号: 307010 - 查看本文应用于的产品
本文的发布号曾为 CHS307010
这篇文章的 Microsoft Visual Basic.NET 版本,请参阅 301070.
这篇文章是指以下 Microsoft.NET Framework 类库命名空间:
  • System.IO
  • System.Security
  • System.Security.Cryptography
注意本文不适用于 Microsoft.NET Framework 2.0。
展开全部 | 关闭全部

本文内容

概要

本文介绍如何使用不是由 Microsoft.NET Framework 加密一个文本文件为不可读的状态,然后解密该文本文件回其原始格式提供的加密类。

要求

下面的列表列出了推荐使用的硬件、 软件、 网络基础结构和服务包,您必须具有:
  • Microsoft Windows 2000 专业版、 Windows 2000 服务器,Windows 2000 高级服务器、 Windows NT 4.0 服务器或 Microsoft Windows XPProfessional
  • Microsoft Visual Studio 2005年或 Microsoft Visual Studio.NET

加密和解密

在 Microsoft.NET Framework 中的System.Security.Cryptographic命名空间提供了多种工具,以帮助您与加密和解密。CryptoStream类是一个提供了许多类。CryptoStream类旨在进行加密或解密的内容,因为它传输出到文件。

加密文件

若要加密文件,请执行以下步骤:
  1. 开始 Visual Studio 2005或 Visual Studio.NET。
  2. 单击Visual C#项目,下,然后单击模板下的控制台应用程序。Visual C#.NET 创建一个静态的类,以及一个空的main ()过程。
  3. 在您执行以下名称空间使用using语句 (如下面的示例代码中所示):
    • 系统
    • System.Security
    • System.Security.Cryptography
    • System.Text
    • System.IO
    因此,您不需要从 thesenamespaces 以后在代码中限定声明。您必须使用这些语句之前任何 otherdeclarations。
    using System;
    using System.IO;
    using System.Security;
    using System.Security.Cryptography;
    using System.Runtime.InteropServices;
    using System.Text;
    					
  4. 生成机密密钥来加密和解密数据。DESCryptoServiceProvider基于对称加密算法。Symmetricencryption 需要一个密钥和一个初始化向量 (IV) 加密请。要解密的数据,必须具有相同的密钥和 IV。您的 mustalso 使用相同的加密算法。您可以通过下列方法之一的 usingeither 生成密钥:
    • 方法 1您可以提示用户输入密码。然后,使用密码用作密钥和 IV。
    • 方法 2创建对称加密类的新实例时,新的密钥和 IV 是自动创建的会话。使用密钥和 IV 所生成的托管对称加密类进行加密和解密文件。

      有关如何生成和分发密钥的详细信息,请参阅 Microsoft.NET Framework SDK 文档中,或请参阅下面的 Microsoft 开发人员网络 (MSDN) Web 站点:
      生成密钥用于加密和解密
  5. 添加下面的函数,以生成新的密钥为 asession (按方法 2 中的步骤 4 所述):
    //  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(ref string 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();
    
    	// Use the Automatically generated key for Encryption. 
    	return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
    }
  6. 创建名为EncryptFile的类中的方法。EncryptFile类必须具有以下三个参数:
    • sInputFilename
    • sOutputFilename
    • sKey(密钥用来加密和解密文件。)
    static void EncryptFile(string sInputFilename,
    		string sOutputFilename,
    		string sKey)
    					
  7. EncryptFile的过程中,创建一个输入文件流对象,并输出文件流对象。这些对象可以是读取和写入到 targetfiles。
    FileStream fsInput = new FileStream(sInputFilename, 
    				FileMode.Open, 
    				FileAccess.Read);
    
    FileStream fsEncrypted = new FileStream(sOutputFilename, 
    				FileMode.Create, 
    				FileAccess.Write);
    					
  8. 声明DESCryptoServiceProvider类的一个实例。这表示实际的加密和 actualdecryption 技术,用于在文件上。在这种情况下,如果您更愿意使用 RSAsecutiry 或 cryptographictechnique 的另一种可以创建不同的提供程序。
    DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
    					
  9. Yoursecret 键作为字节数组时,必须提供加密提供程序。System.Text命名空间提供了一个名为GetBytes()的函数。作为其编码功能的一部分, GetBytes()函数接受一个字符串,然后返回一个字节数组。应的密钥是不同的各种加密技术采用的。例如,数据加密标准 (DES) 采用 64 位密钥,它等于 8 个字节或 8 个字符。

    如果您未提供密钥,提供程序 randomlygenerates 一个。这将成功地加密文件,但是没有任何方法 todecrypt 文件。请注意您还必须提供初始化 vector(IV)。此值用作加密的一部分。类似的键,如果未提供值生成 IV israndomly。因为值必须 bethe 用于加密和解密相同,所以不能让这些值的 randomgeneration。
    DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
    DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
    					
  10. 使用的加密提供程序来获取 encryptingobject (CreateEncryptor) 创建CryptoStream类的一个实例,现有输出文件流对象的构造函数的一部分。
    ICryptoTransform desencrypt = DES.CreateEncryptor();
    CryptoStream cryptostream = new CryptoStream(fsEncrypted, 
    					desencrypt, 
    					CryptoStreamMode.Write);
    					
  11. 在输入文件中,阅读然后写出到输出文件。通过CryptoStream对象在文件使用密钥加密该 youprovided。
    byte[] bytearrayinput = new byte[fsInput.Length - 1];
    fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
    cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
    					

解密文件

要解密文件,请执行以下步骤:
  1. 创建一个方法,并命名该按钮DecryptFile.解密过程是类似于 theencryption 进程,但是, DecryptFile过程从EncryptFile过程的两个主要区别。
    • 而不是CreateEncryptor使用CreateDecryptor来创建CryptoStream对象,用于指定如何使用该对象。
    • 解密的文本写入目标文件, CryptoStream对象是现在而不是目标流的来源。
    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();
    }
    					
  2. 调用EncryptFileDecryptFilemain ()过程中添加以下行:
    static void Main()
    {
          // 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(@"C:\MyData.txt", 
             @"C:\Encrypted.txt", 
             sSecretKey);
    
          // Decrypt the file.
          DecryptFile(@"C:\Encrypted.txt", 
             @"C:\Decrypted.txt", 
             sSecretKey);
    
          // Remove the key from memory. 
          ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
          gch.Free();
    }
  3. 保存该文件。运行您的应用程序。请确保该程序使用该输入的文件名称指向 existingfile 的 thepath。

测试过程

与文本 (.txt) 文件,以确认代码加密和解密文件正确测试此代码。确保原始文件,而不是解密到一个新的文件 (如本文中的main ()过程) 的文件。检查解密后的文件,然后与原文件进行比较。

完整的代码列表

using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;

namespace CSEncryptDecrypt
{
   class Class1
   {
      //  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();

         // 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();
      } 

      static void Main()
      {
         // 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(@"C:\MyData.txt", 
            @"C:\Encrypted.txt", 
            sSecretKey);

         // Decrypt the file.
         DecryptFile(@"C:\Encrypted.txt", 
            @"C:\Decrypted.txt", 
            sSecretKey);

         // Remove the Key from memory. 
         ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
         gch.Free();
      }
   }
}

参考

关于加密,以及使用.NET 的加密功能的详细信息,请参阅下面的 MSDN 网站:
System.Security.Cryptography 命名空间
Microsoft.NET Framework 开发人员中心

属性

文章编号: 307010 - 最后修改: 2013年11月1日 - 修订: 5.0
这篇文章中的信息适用于:
  • Microsoft Visual C# 2005
  • Microsoft Visual C# .NET 2003 标准版
  • Microsoft Visual C# .NET 2002 标准版
关键字:?
kbsecurity kbio kbcrypt kbhowtomaster kbmt KB307010 KbMtzh
机器翻译
重要说明:本文是由 Microsoft 机器翻译软件进行的翻译并可能由 Microsoft 社区通过社区翻译机构(CTF)技术进行后期编辑,或可能是由人工进行的翻译。Microsoft 同时向您提供机器翻译、人工翻译及社区后期编辑的文章,以便对我们知识库中的所有文章以多种语言提供访问。翻译的文章可能存在词汇、句法和/或语法方面的错误。Microsoft 对由于内容的误译或客户对内容的使用所导致的任何不准确、错误或损失不承担责任。
点击这里察看该文章的英文版: 307010
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com