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

 本文引入的命名空间:

 

  • System.IO
  • System.Security
  • System.Security.Cryptography

     

     本文介绍如何使用 Microsoft .NET Framework 提供的加密类对文本文件进行加密以使其处于不可读状态,然后再对该信息进行解密,以恢复到原来的格式。
    回到顶端


    要求
    下面列出了推荐使用的硬件、软件、网络架构以及所需的 Service Pack: 
    Microsoft Windows 2000 Professional、Windows 2000 Server、Windows 2000 Advanced Server、Windows NT 4.0 Server 或 Microsoft Windows XP Professional
    Microsoft Visual Studio 2005 或 Microsoft Visual Studio .NET
    回到顶端


    加密和解密
    Microsoft .NET Framework 中的 System.Security.Cryptographic 命名空间提供了多种帮助您加密和解密的工具。CryptoStream 类就是所提供的诸多类中的一个。CryptoStream 类设计用于在内容以流的形式输出到文件时加密和解密内容。
    回到顶端
    加密文件
    要加密文件,请按照下列步骤操作: 
    启动 Visual Studio 2005 或 Visual Studio .NET。
    单击“项目”下的“Visual C#”,然后单击“模板”下的“控制台应用程序”。Visual C# .NET 为您创建一个静态类,以及一个空的 Main() 过程。
    对以下命名空间使用 using 语句(如以下示例代码中所示): 
    System
    System.Security
    System.Security.Cryptography
    System.Text
    System.IO
    这样,在后面的代码中就不必从这些命名空间中限定声明了。这些语句必须位于任何其他声明之前。
    using System;
    using System.IO;
    using System.Security;
    using System.Security.Cryptography;
    using System.Runtime.InteropServices;
    using System.Text;
         

    生成密钥以加密和解密数据。DESCryptoServiceProvider 基于一种对称加密算法。对称加密需要密钥和初始化矢量 (IV) 来加密数据。要解密该数据,您必须拥有此同一密钥和 IV。您还必须使用相同的加密算法。您可以使用下列方法之一生成密钥: 
    方法 1 您可以提示用户输入密码。然后,将此密码用作密钥和 IV。
    方法 2 当您创建对称加密类的新实例时,将为会话自动创建一个新的密钥和 IV。使用由受管理的对称加密类生成的密钥和 IV 来加密和解密文件。

    有关如何生成和分发密钥的更多信息,请参见 Microsoft .NET Framework SDK 文档,或访问以下 Microsoft Developer Network (MSDN) 网站:
    生成加密密钥和解密密钥
    http://msdn.microsoft.com/library/default.asp?url=/library/zh-cn/cpguide/html/cpcongeneratingkeysforencryptiondecryption.asp(http://msdn.microsoft.com/library/default.asp?url=/library/zh-cn/cpguide/html/cpcongeneratingkeysforencryptiondecryption.asp
    添加以下函数为会话生成一个新的密钥(按照步骤 4 的方法 2 中的说明):
    //  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);
    }

    在您的类中创建一个命名为 EncryptFile 的方法。EncryptFile 类必须具有以下 3 个参数: 
    sInputFilename
    sOutputFilename
    sKey(用于加密和解密文件的密钥。)
    static void EncryptFile(string sInputFilename,
      string sOutputFilename,
      string sKey)
         

    在 EncryptFile 过程中,创建一个输入 FileStream 对象和一个输出 FileStream 对象。这些对象可以从目标文件中读取和向其中写入。
    FileStream fsInput = new FileStream(sInputFilename, 
        FileMode.Open, 
        FileAccess.Read);

    FileStream fsEncrypted = new FileStream(sOutputFilename, 
        FileMode.Create, 
        FileAccess.Write);
         

    声明一个 DESCryptoServiceProvider 类的实例。这表示对文件使用的实际加密和解密技术。此时,如果您更喜欢使用 RSAsecutiry 或另一种加密技术,则可以创建一个不同的提供程序。
    DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
         

    必须以字节数组的形式给加密提供程序提供密钥。System.Text 命名空间提供了一个名为 GetBytes() 的函数。GetBytes() 函数的编码特征之一是,它取一个字符串,然后返回一个字节数组。各种加密技术采用的密钥长度是不相同的。例如,数据加密标准 (DES) 使用等于 8 个字节或 8 个字符的 64 位密钥。

    如果您不提供密钥,提供程序就会随机生成一个密钥。这将成功地加密文件,但是无法解密文件。请注意,您还必须提供初始化矢量 (IV)。该值用作加密的一部分。与密钥相似,如果您未提供 IV,提供程序就会随机生成一个。由于该值对于加密和解密必须相同,所以不能让提供程序随机生成这些值。
    DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
    DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
         

    创建一个 CryptoStream 类的实例,方法是:使用加密提供程序获得一个加密对象(CreateEncryptor),并将现有的输出 FileStream 对象作为构造函数的一部分。
    ICryptoTransform desencrypt = DES.CreateEncryptor();
    CryptoStream cryptostream = new CryptoStream(fsEncrypted, 
         desencrypt, 
         CryptoStreamMode.Write);
         

    读入输入文件,然后写出到输出文件。传递 CryptoStream 对象,文件将使用您提供的密钥加密。
    byte[] bytearrayinput = new byte[fsInput.Length - 1];
    fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
    cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
         

    回到顶端


    解密文件
    要解密文件,请按照下列步骤操作: 
    创建一个方法,然后将它命名为 DecryptFile。解密过程与加密过程相似,但 DecryptFile 过程与 EncryptFile 过程有两个关键区别。 
    CryptoStream 对象是使用 CreateDecryptor 而非 CreateEncryptor 创建的,这将指定对象的使用方式。
    在将解密的文本写入到目标文件时,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();
    }
         

    将以下几行添加到 Main() 过程,以调用 EncryptFile 和 DecryptFile:
    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();
    }

    保存文件。运行您的应用程序。确保输入文件名使用的路径指向一个现有文件。
    测试过程
    用一个文本文件 (.txt) 测试此代码,确认它可对此文件进行正确的加密和解密。确保将文件解密到一个新文件(如本文中的 Main() 过程中所示),而不是解密到原来的文件中。检查解密后的文件,然后与原文件进行比较。
    回到顶端


    完整代码列表

    [c-sharp]  view plain copy
    1. using System;  
    2. using System.IO;  
    3. using System.Security;  
    4. using System.Security.Cryptography;  
    5. using System.Runtime.InteropServices;  
    6. using System.Text;  
    7.   
    8. namespace CSEncryptDecrypt  
    9. {  
    10.    class Class1  
    11.    {  
    12.       //  Call this function to remove the key from memory after use for security  
    13.       [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")]  
    14.       public static extern bool ZeroMemory(IntPtr Destination, int Length);  
    15.     
    16.       // Function to Generate a 64 bits Key.  
    17.       static string GenerateKey()   
    18.       {  
    19.          // Create an instance of Symetric Algorithm. Key and IV is generated automatically.  
    20.          DESCryptoServiceProvider desCrypto =(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();  
    21.   
    22.          // Use the Automatically generated key for Encryption.   
    23.          return ASCIIEncoding.ASCII.GetString(desCrypto.Key);  
    24.       }  
    25.   
    26.       static void EncryptFile(string sInputFilename,  
    27.          string sOutputFilename,   
    28.          string sKey)   
    29.       {  
    30.          FileStream fsInput = new FileStream(sInputFilename,   
    31.             FileMode.Open,   
    32.             FileAccess.Read);  
    33.   
    34.          FileStream fsEncrypted = new FileStream(sOutputFilename,   
    35.             FileMode.Create,   
    36.             FileAccess.Write);  
    37.          DESCryptoServiceProvider DES = new DESCryptoServiceProvider();  
    38.          DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  
    39.          DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  
    40.          ICryptoTransform desencrypt = DES.CreateEncryptor();  
    41.          CryptoStream cryptostream = new CryptoStream(fsEncrypted,   
    42.             desencrypt,   
    43.             CryptoStreamMode.Write);   
    44.   
    45.          byte[] bytearrayinput = new byte[fsInput.Length];  
    46.          fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);  
    47.          cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);  
    48.          cryptostream.Close();  
    49.          fsInput.Close();  
    50.          fsEncrypted.Close();  
    51.       }  
    52.   
    53.       static void DecryptFile(string sInputFilename,   
    54.          string sOutputFilename,  
    55.          string sKey)  
    56.       {  
    57.          DESCryptoServiceProvider DES = new DESCryptoServiceProvider();  
    58.          //A 64 bit key and IV is required for this provider.  
    59.          //Set secret key For DES algorithm.  
    60.          DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  
    61.          //Set initialization vector.  
    62.          DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  
    63.   
    64.          //Create a file stream to read the encrypted file back.  
    65.          FileStream fsread = new FileStream(sInputFilename,   
    66.             FileMode.Open,   
    67.             FileAccess.Read);  
    68.          //Create a DES decryptor from the DES instance.  
    69.          ICryptoTransform desdecrypt = DES.CreateDecryptor();  
    70.          //Create crypto stream set to read and do a   
    71.          //DES decryption transform on incoming bytes.  
    72.          CryptoStream cryptostreamDecr = new CryptoStream(fsread,   
    73.             desdecrypt,  
    74.             CryptoStreamMode.Read);  
    75.          //Print the contents of the decrypted file.  
    76.          StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);  
    77.          fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());  
    78.          fsDecrypted.Flush();  
    79.          fsDecrypted.Close();  
    80.       }   
    81.   
    82.       static void Main()  
    83.       {  
    84.          // Must be 64 bits, 8 bytes.  
    85.          // Distribute this key to the user who will decrypt this file.  
    86.          string sSecretKey;  
    87.            
    88.          // Get the Key for the file to Encrypt.  
    89.          sSecretKey = GenerateKey();  
    90.   
    91.          // For additional security Pin the key.  
    92.          GCHandle gch = GCHandle.Alloc( sSecretKey,GCHandleType.Pinned );  
    93.            
    94.          // Encrypt the file.          
    95.          EncryptFile(@"C:/MyData.txt",   
    96.             @"C:/Encrypted.txt",   
    97.             sSecretKey);  
    98.   
    99.          // Decrypt the file.  
    100.          DecryptFile(@"C:/Encrypted.txt",   
    101.             @"C:/Decrypted.txt",   
    102.             sSecretKey);  
    103.   
    104.          // Remove the Key from memory.   
    105.          ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);  
    106.          gch.Free();  
    107.       }  
    108.    }  
    109. }  


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值