惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Palo Alto Networks Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
S
Schneier on Security
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cyberwarzone
Cyberwarzone
Apple Machine Learning Research
Apple Machine Learning Research
S
SegmentFault 最新的问题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
GbyAI
GbyAI
Security Latest
Security Latest
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
TaoSecurity Blog
TaoSecurity Blog
C
Cisco Blogs
博客园 - 【当耐特】
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
B
Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
The Last Watchdog
The Last Watchdog
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志
Project Zero
Project Zero
WordPress大学
WordPress大学
L
LINUX DO - 最新话题
F
Fortinet All Blogs
L
LINUX DO - 热门话题
PCI Perspectives
PCI Perspectives
Simon Willison's Weblog
Simon Willison's Weblog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
MongoDB | Blog
MongoDB | Blog
Latest news
Latest news
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
The Hacker News
The Hacker News
爱范儿
爱范儿
O
OpenAI News
J
Java Code Geeks
T
The Exploit Database - CXSecurity.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - 星期六

C# winform授权:获取cpu和硬盘的序列号,得到机器码 批量替换文本文件中的字符 获取主板及硬盘序列号 - 星期六 - 博客园 .net安装部署“Error 1001 在初始化安装时发生异常” 的解决方法 解决.net绘制的 WinForm 在 windows7下变形的方法。 ppc通过蓝牙与电脑同步时无ActiveSync服务的解决方法。 winfrom中的几个界面皮肤控件 如何弹出一个模式窗口来显示进度条 .net 实现移动控件位置 如何在安装后自动运行程序? 调试自定义操作/安装程序类的方法 利用TimerCallback实现timer传递参数 网页中下载灰鸽子病毒的 SCRIPT 一段控制对象透明度的style. ASP.net 把 DataGrid 数据导出到 Excel . 用C#实现语音技术 ASP.NET 用读取二进制代码的方法在页面上显示指定图片。 c# 8条语句实现屏幕抓图 几条SQLl查询语句
如何使用 Visual C# 加密和解密文件
星期六 · 2009-05-15 · via 博客园 - 星期六

原文:
http://support.microsoft.com/kb/307010/zh-cn

本文介绍如何使用 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 类设计用于在内容以流的形式输出到文件时加密和解密内容。

加密文件

要加密文件,请按照下列步骤操作:

  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) 网站:

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


上面代码不能正确还原中文字符,只需要小做修改

        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,Encoding.GetEncoding("gb2312")).ReadToEnd());
            fsDecrypted.Flush();
            fsDecrypted.Close();
        }