zoukankan      html  css  js  c++  java
  • 如何使用 Visual C# 加密和解密文件

    加密和解密

    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
      • 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;
          
          
    4. 生成密钥以加密和解密数据。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)
    5. 添加以下函数为会话生成一个新的密钥(按照步骤 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);
          }
          
          
    6. 在您的类中创建一个命名为 EncryptFile 的方法。EncryptFile 类必须具有以下 3 个参数:
      • sInputFilename
      • sOutputFilename
      • sKey(用于加密和解密文件的密钥。)
      static void EncryptFile(string sInputFilename,           string sOutputFilename,         string sKey)                                    
          
    7. EncryptFile 过程中,创建一个输入 FileStream 对象和一个输出 FileStream 对象。这些对象可以从目标文件中读取和向其中写入。
      FileStream fsInput = new FileStream(sInputFilename,                            FileMode.Open,                          FileAccess.Read);
          FileStream fsEncrypted = new FileStream(sOutputFilename,                               FileMode.Create,                                FileAccess.Write);
          
          
    8. 声明一个 DESCryptoServiceProvider 类的实例。这表示对文件使用的实际加密和解密技术。此时,如果您更喜欢使用 RSAsecutiry 或另一种加密技术,则可以创建一个不同的提供程序。
      DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
          
          
    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 对象作为构造函数的一部分。
      ICryptoTransform desencrypt = DES.CreateEncryptor();
          CryptoStream cryptostream = new CryptoStream(fsEncrypted,                                    desencrypt,                                     CryptoStreamMode.Write);
          
          
    11. 读入输入文件,然后写出到输出文件。传递 CryptoStream 对象,文件将使用您提供的密钥加密。
      byte[] bytearrayinput = new byte[fsInput.Length - 1];
          fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
          cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
          
          

    解密文件

    要解密文件,请按照下列步骤操作:
    1. 创建一个方法,然后将它命名为 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();
          }
          
          
    2. 将以下几行添加到 Main() 过程,以调用 EncryptFileDecryptFile
      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. 保存文件。运行您的应用程序。确保输入文件名使用的路径指向一个现有文件。

    测试过程

    用一个文本文件 (.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 命名空间http:/...

    有关加密以及使用 .NET 的加密功能的更多信息,请访问下面的 MSDN 网站:
    System.Security.Cryptography 命名空间
    http://msdn2.microsoft.com/zh-cn/library/system.security.cryptography(VS.80).aspx (http://msdn2.microsoft.com/zh-cn/library/system.security.cryptography(VS.80).aspx)
    Microsoft .NET Framework 开发中心
    http://msdn2.microsoft.com/zh-cn/netframework/default.aspx (http://msdn2.microsoft.com/zh-cn/netframework/default.aspx)
    有关 Visual C# .NET 的更多一般信息,请访问以下 Usenet 新闻组:
    microsoft.public.dotnet.languages.csharp (http://go.microsoft.com/fwlink
  • 相关阅读:
    (三)OpenCV-Python学习—图像平滑
    (二)OpenCV-Python学习—对比度增强
    (一)OpenCV-Python学习—基础知识
    mongodb的安装及使用
    python操作MySQL数据库的三个模块
    mysql数据库学习二
    (八)爬虫之js调试(登陆知乎)
    经典Paxos算法笔记
    ThreadPoolExecutor源码解读
    FutureTask源码解读
  • 原文地址:https://www.cnblogs.com/springxie/p/1356087.html
Copyright © 2011-2022 走看看