您的位置:首页 > 编程语言 > C#

c#加密解密文件

2011-07-03 21:43 176 查看
c#加密解密文件
利用 .NET 的原生的类库对文件、字符串进行加解密可以说是很简单的一件事情(在这里只讨论对称加解密)。在加解密的时候,最核心事情实际上就是创建一个 CryptoStream 对象,将数据流链接到加密/解密转换的流,然后再将数据写入流中去,这样就完成了一次加密/解密操作。
可能用简单的代码片段更加明白一些,当然,如果这些类一点都不熟的话,还是需要看MSDN的。

public static byte[] Encrypt(String plainText, ICryptoTransform encryptTransform)
        {
            try
            {
                // Create a memory stream.
                MemoryStream ms = new MemoryStream();

                // Create a CryptoStream using the memory stream.  
                CryptoStream encStream = new CryptoStream(ms, encryptTransform, CryptoStreamMode.Write);

                // Create a StreamWriter to write a string to the stream.
                StreamWriter sw = new StreamWriter(encStream);

                // Write the plain text to the stream.
                sw.WriteLine(plainText);

                // Close the StreamWriter and CryptoStream.
                sw.Close();
                encStream.Close();

                // Get an array of bytes that represents the memory stream.
                byte[] buffer = ms.ToArray();

                // Close the memory stream.
                ms.Close();

                // Return the encrypted byte array.
                return buffer;
            }
            catch (System.Exception ex)
            {
            }

            return null;
        }
如上代码:
其中参数 encryptTransform 就是要进行加密转换的流,该流是继承于 ICryptoTransform 对象,当然,如果是要解密,那就需要传入解密的转换流。
加密过程已通过注释解释清楚了,相信你能看明白。
但是,有个问题,这些加密、解密的流如何产生出来?
实际上,在进行加密、解密的时候,他们是通过加密算法对象生成出来的。在对称加密算法的基类: SymmetricAlgorithm 类中,我们看到,有两个接口:
当在派生类中重写时,用指定的 Key 属性和初始化向量 (IV) 创建对称解密器对象。
public abstract ICryptoTransform CreateDecryptor(
	byte[] rgbKey,
	byte[] rgbIV
)
public abstract ICryptoTransform CreateEncryptor(
	byte[] rgbKey,
	byte[] rgbIV
)

从这两个接口来看,只要是继承于对称加密基类的(如DESCryptoServiceProvider, RijndaelManaged,TripleDESCryptoServiceProvider),都是需要实现这两个接口的。
OK,废话说了一堆,直接写代码吧。
这里分为两个类,其中一个类用于创建加密Key(或者称为加密Provider)----GTXKeyManager,它专注于创建各种类型的加密key和其相关操作,另一个专注于加密和解密----GTXSymmetricCrypt。

/*!
 * @file GTXKeyManager.cs
 * 
 * @brief This file implements the class of GTXKeyManager.
 *        This class is used to create encrypt or decrypt provider.
 * 
 * Copyright (C) 2011, GTX.
 * 
 * @author Liu Lin
 * @date 2011/7/01
 */

using System;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Security.Principal;
using GTXUtility.DataStorage.Serializer;

namespace GTXUtility.Security.Crypt
{
    public class GTXKeyManager
    {
        /// <summary>
        /// Defines Symmetric Encryption Algorithm types.
        /// </summary>
        /// <remarks>The RC2 algorithm cannot be used for GTXXmlCrypt class to encrypt/decrypt XML.</remarks>
        public enum SymmetricAlgTypes
        {
            Unknown, 
            DES = 1,
            AES128,     // Rijndael 128
            AES192,     // Rijndael 192
            AES256,     // Rijndael 256
            TripleDES,
            RC2,
        }

        /// <summary>
        /// Create a Symmetric Encryption Algorithm object.
        /// </summary>
        /// <param name="salType">Specified symmetric encryption algorithm type.</param>
        /// <returns>If create success, returns the Symmetric Encryption Algorithm object.
        /// Otherwise, return null object.</returns>
        public static SymmetricAlgorithm CreateSymmetricAlgorithm(SymmetricAlgTypes salType)
        {
            SymmetricAlgorithm symAlg = null;
            switch (salType)
            {
                case SymmetricAlgTypes.DES:
                    symAlg = SymmetricAlgorithm.Create("DES");
                    break;
                case SymmetricAlgTypes.AES128:
                    symAlg = SymmetricAlgorithm.Create("Rijndael");
                    symAlg.KeySize = 128;
                    break;
                case SymmetricAlgTypes.AES192:
                    symAlg = SymmetricAlgorithm.Create("Rijndael");
                    symAlg.KeySize = 192;
                    break;
                case SymmetricAlgTypes.AES256:
                    symAlg = SymmetricAlgorithm.Create("Rijndael");
                    symAlg.KeySize = 256;
                    break;
                case SymmetricAlgTypes.TripleDES:
                    symAlg = SymmetricAlgorithm.Create("TripleDES");
                    break;
                case SymmetricAlgTypes.RC2:
                    symAlg = SymmetricAlgorithm.Create("RC2");
                    break;
                default:
                    break;
            }
            return symAlg;
        }

        /// <summary>
        /// Get the symmetric encryption algorithm type.
        /// </summary>
        /// <param name="key">Specified encryption key.</param>
        /// <returns>Return the symmetric encryption algorithm type.</returns>
        public static SymmetricAlgTypes GetSymmetricAlgorithmType(SymmetricAlgorithm key)
        {
            SymmetricAlgTypes type = SymmetricAlgTypes.Unknown;
            if (key is DES)
            {
                type = SymmetricAlgTypes.DES;
            }
            else if (key is Rijndael)
            {
                switch ((key as Rijndael).KeySize)
                {
                    case 128:
                        type = SymmetricAlgTypes.AES128;
                        break;
                    case 192:
                        type = SymmetricAlgTypes.AES192;
                        break;
                    case 256:
                        type = SymmetricAlgTypes.AES256;
                        break;
                    default:
                        break;
                }
            }
            else if (key is TripleDES)
            {
                type = SymmetricAlgTypes.TripleDES;
            }

            return type;
        }

        /// <summary>
        /// Generate symmetric encryption algorithm key's data.
        /// </summary>
        /// <param name="salType">Specified symmetric encryption algorithm type.</param>
        /// <returns>Return symmetric encryption algorithm key's data.</returns>
        public static byte[] GenerateKey(SymmetricAlgTypes salType)
        {
            SymmetricAlgorithm symAlg = CreateSymmetricAlgorithm(salType);
            return symAlg.Key;
        }

        /// <summary>
        /// Generate symmetric encryption algorithm key's IV data.
        /// </summary>
        /// <param name="salType">Specified symmetric encryption algorithm type.</param>
        /// <returns>Return symmetric encryption algorithm key's IV data.</returns>
        public static byte[] GenerateIV(SymmetricAlgTypes salType)
        {
            SymmetricAlgorithm symAlg = CreateSymmetricAlgorithm(salType);
            return symAlg.IV;
        }
    }
}
当然,在GTXKeyManager类中还有其它事情需要做,如加密key的导入导出等工作。这里我就不再粘贴代码了。
/*!
* @file GTXXmlCrypt.cs
*
* @brief This file implements the class of GTXSymmetricCrypt.
* This class is used to crypt or decrypt string or file with symmetric algorithm.
*
* Copyright (C) 2011, GTX.
*
* @author Liu Lin
* @date 2011/7/01
*/

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

namespace GTXUtility.Security.Crypt
{
/// <summary>
/// This class is used to crypt or decrypt string or file with symmetric algorithm.
/// </summary>
public class GTXSymmetricCrypt
{
/// <summary>
/// Create a encryption/decryption transform. The transform object is used to encrypt or decrypt.
/// </summary>
/// <param name="symAlgKey">Specified symmetric encryption algorithm provider (key).</param>
/// <param name="bCreateEncryptor">If true, create encryption transform, otherwise, create decryption transform</param>
/// <returns>Return the encryption/decryption transform.</returns>
public static ICryptoTransform CreateCryptoTransform(SymmetricAlgorithm symAlgKey, bool bCreateEncryptor)
{
try
{
// If bCreateEncryptor is true, create a encryption ICryptoTransform;
// else, create a decryption ICryptoTransform;
return
bCreateEncryptor ?
symAlgKey.CreateEncryptor(symAlgKey.Key, symAlgKey.IV) :
symAlgKey.CreateDecryptor(symAlgKey.Key, symAlgKey.IV);
}
catch (System.Exception ex)
{
}

return null;
}

/// <summary>
/// Create a encryption/decryption transform. The transform object is used to encrypt or decrypt.
/// </summary>
/// <param name="symAlgType">Specified symmetric algorithm type.</param>
/// <param name="rgbKey">Specified key's data of symmetric encryption/decryption algorithm.</param>
/// <param name="rgbIV">Specified key's IV of symmetric encryption/decryption algorithm.</param>
/// <param name="bCreateEncryptor">If true, create encryption transform, otherwise, create decryption transform</param>
/// <returns>Return the encryption/decryption transform.</returns>
public static ICryptoTransform CreateCryptoTransform(
GTXKeyManager.SymmetricAlgTypes symAlgType,
byte[] rgbKey,
byte[] rgbIV,
bool bCreateEncryptor)
{
try
{
// Create a crypt provider by specified type.
SymmetricAlgorithm symAlg = GTXKeyManager.CreateSymmetricAlgorithm(symAlgType);

// If bCreateEncryptor is true, create a encryption ICryptoTransform;
// else, create a decryption ICryptoTransform;
return
bCreateEncryptor ?
symAlg.CreateEncryptor(rgbKey, rgbIV) :
symAlg.CreateDecryptor(rgbKey, rgbIV);
}
catch (System.Exception ex)
{
}

return null;
}

/// <summary>
/// Encrypt a string with encryption transform.
/// </summary>
/// <param name="plainText">Specified sting which needs to be encrypted.</param>
/// <param name="encryptTransform">Specified transform object which used to encrypt.</param>
/// <returns>Return the encrypted data. If failed, return null.</returns>
public static byte[] Encrypt(String plainText, ICryptoTransform encryptTransform) { try { // Create a memory stream. MemoryStream ms = new MemoryStream(); // Create a CryptoStream using the memory stream. CryptoStream encStream = new CryptoStream(ms, encryptTransform, CryptoStreamMode.Write); // Create a StreamWriter to write a string to the stream. StreamWriter sw = new StreamWriter(encStream); // Write the plain text to the stream. sw.WriteLine(plainText); // Close the StreamWriter and CryptoStream. sw.Close(); encStream.Close(); // Get an array of bytes that represents the memory stream. byte[] buffer = ms.ToArray(); // Close the memory stream. ms.Close(); // Return the encrypted byte array. return buffer; } catch (System.Exception ex) { } return null; }

/// <summary>
/// Encrypt the specified source file to the specified destination file.
/// </summary>
/// <param name="sourceFilePath">Specified source file which needs to be encrypted.</param>
/// <param name="destFilePath">Specified destination file.</param>
/// <param name="encryptTransform">Specified transform object which used to encrypt.</param>
/// <returns>If encrypt file succeed, return true, otherwise, return false.</returns>
public static bool EncryptFile(String sourceFilePath, String destFilePath, ICryptoTransform encryptTransform)
{
if (!File.Exists(sourceFilePath))
{
return false;
}

try
{
FileStream fsSource = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read);
FileStream fsDestination = new FileStream(destFilePath, FileMode.OpenOrCreate, FileAccess.Write);

// Create a CryptoStream using the memory stream.
CryptoStream encStream = new CryptoStream(fsDestination, encryptTransform, CryptoStreamMode.Write);

// Create a StreamWriter to write a string to the stream.
StreamWriter sw = new StreamWriter(encStream, Encoding.UTF8);

// Create a StreamReader to read the file stream to stream.
StreamReader sr = new StreamReader(fsSource, Encoding.UTF8);

// Print the contents of the destination file.
sw.WriteLine(sr.ReadToEnd());
sw.Flush();

// Close the streams.
sr.Close();
sw.Close();
encStream.Close();
fsSource.Close();
fsDestination.Close();

return true;
}
catch (System.Exception ex)
{
}

return false;
}

/// <summary>
/// Decrypt the encrypted byte array into string with decryption transform.
/// </summary>
/// <param name="cypherText">Specified encrypted byte array.</param>
/// <param name="decryptTransform">Specified transform object which used to decrypt.</param>
/// <returns>Returns the decrypt string.</returns>
public static String Decrypt(byte[] cypherText, ICryptoTransform decryptTransform)
{
try
{
// Create a memory stream to the passed buffer.
MemoryStream ms = new MemoryStream(cypherText);

// Create a CryptoStream using the memory stream and the CSP DES key.
CryptoStream decStream = new CryptoStream(ms, decryptTransform, CryptoStreamMode.Read);

// Create a StreamReader for reading the stream.
StreamReader sr = new StreamReader(decStream);

// Read the stream as a string.
string val = sr.ReadLine();

// Close the streams.
sr.Close();
decStream.Close();
ms.Close();

return val;
}
catch (System.Exception ex)
{
}

return String.Empty;
}

/// <summary>
/// Decrypt the specified source file to the specified destination file.
/// </summary>
/// <param name="sourceFilePath">Specified source file which needs to be decrypted.</param>
/// <param name="destFilePath">Specified destination file.</param>
/// <param name="encryptTransform">Specified transform object which used to decrypt.</param>
/// <returns>If decrypt file succeed, return true, otherwise, return false.</returns>
public static bool DecryptFile(String sourceFilePath, String destFilePath, ICryptoTransform decryptTransform)
{
if (!File.Exists(sourceFilePath))
{
return false;
}

try
{
FileStream fsSource = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read);
FileStream fsDestination = new FileStream(destFilePath, FileMode.OpenOrCreate, FileAccess.Write);

// Create a CryptoStream using the memory stream and the CSP DES key.
CryptoStream decStream = new CryptoStream(fsSource, decryptTransform, CryptoStreamMode.Read);

// Create a StreamWriter to write a string to the stream.
StreamWriter sw = new StreamWriter(fsDestination, Encoding.UTF8);

// Create a StreamReader to read the decrypted stream.
StreamReader sr = new StreamReader(decStream, Encoding.UTF8);

// Print the contents of the destination file.
sw.WriteLine(sr.ReadToEnd());
sw.Flush();

// Close the streams.
sr.Close();
sw.Close();
decStream.Close();
fsSource.Close();
fsDestination.Close();

return true;
}
catch (System.Exception ex)
{
}

return false;
}
}
}
测试代码:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using GTXUtility.Security.Crypt;

namespace TestUtility
{
    public class TestSymmetricCrypt
    {
        // The secret key to use for the DES symmetric algorithm.
        public static readonly byte[] Default_DES_Key = { 34, 63, 63, 109, 63, 119, 63, 63 };
        // The initialization vector to use for the DES symmetric algorithm.
        public static readonly byte[] Default_DES_IV = { 34, 63, 63, 109, 63, 119, 63, 63 };

        private readonly static String _plainText1 = "这是明文。This is a test plain Text!";

        public static void UseDemo()
        {
            Console.WriteLine("Select test type (Default is O): 0: string encryption/decryption, otherwise, test file encryption/decryption");
            String type = Console.ReadLine();
            int nType = type.Equals("0") ? 0 : 1;
            if (0 == nType)
            {
                TestCryptString();
            }
            else
            {
                TestCryptFile();
            }
        }

        public static void TestCryptString()
        {
            Console.WriteLine("\n№ Encrypt/Decrypt Plain Text by specified symmetric algorithm.");
            Console.WriteLine("→ Original Plain Text: {0}", _plainText1);

            // Create a symmetric algorithm encryption provider.
            GTXKeyManager.SymmetricAlgTypes salType = ReadSymmetricAlgType();
            SymmetricAlgorithm symAlg = GTXKeyManager.CreateSymmetricAlgorithm(salType);

            // Create a ICryptoTransform object to encrypt.
            ICryptoTransform encryptTransform = GTXSymmetricCrypt.CreateCryptoTransform(symAlg, true);
            byte[] cypherText = GTXSymmetricCrypt.Encrypt(_plainText1, encryptTransform);
            Console.WriteLine("→ Cypher Text: {0}", Encoding.ASCII.GetString(cypherText));

            // Create a ICryptoTransform object to decrypt.
            ICryptoTransform decryptTransform = GTXSymmetricCrypt.CreateCryptoTransform(symAlg, false);
            String tempPlainText = GTXSymmetricCrypt.Decrypt(cypherText, decryptTransform);
            Console.WriteLine("→ Decrypt Cypher Text: {0}", tempPlainText.ToString());

            //------------------------------------------------------------------------------
            // Use DES Key and IV to encrypt and decrypt string.
            // Create a ICryptoTransform object to encrypt.
            Console.WriteLine("\n№ Encrypt/Decrypt Plain Text by specified Key and IV. (DES)");
            encryptTransform = GTXSymmetricCrypt.CreateCryptoTransform(GTXKeyManager.SymmetricAlgTypes.DES, Default_DES_Key, Default_DES_IV, true);
            cypherText = GTXSymmetricCrypt.Encrypt(_plainText1, encryptTransform);
            Console.WriteLine("→ Cypher Text: {0}", Encoding.ASCII.GetString(cypherText));

            // Create a ICryptoTransform object to decrypt.
            decryptTransform = GTXSymmetricCrypt.CreateCryptoTransform(GTXKeyManager.SymmetricAlgTypes.DES, Default_DES_Key, Default_DES_IV, false);
            tempPlainText = GTXSymmetricCrypt.Decrypt(cypherText, decryptTransform);
            Console.WriteLine("→ Decrypt Cypher Text: {0}", tempPlainText.ToString());
        }

        public static void TestCryptFile()
        {
            Console.WriteLine("Test file Crypt begin...");
            Console.WriteLine("Input file path: (You can drag a file into console without input file path)");

            String filePath = Console.ReadLine();
            if (File.Exists(filePath))
            { 
                using (FileStream fs = new FileStream(filePath, FileMode.Open))
                {
                    StreamReader sr = new StreamReader(fs, Encoding.UTF8);
                    Console.WriteLine("■ Original file:\n{0}", sr.ReadToEnd());
                    sr.Close();
                }

                GTXKeyManager.SymmetricAlgTypes salType = ReadSymmetricAlgType();

                // Create a symmetric algorithm encryption provider.
                SymmetricAlgorithm symAlg = GTXKeyManager.CreateSymmetricAlgorithm(salType);

                // Create a ICryptoTransform object to encrypt.
                ICryptoTransform encryptTransform = GTXSymmetricCrypt.CreateCryptoTransform(symAlg, true);
                if (GTXSymmetricCrypt.EncryptFile(filePath, "Encrypted.txt", encryptTransform))
                {
                    using (FileStream fs = new FileStream("Encrypted.txt", FileMode.Open))
                    {
                        StreamReader sr = new StreamReader(fs, Encoding.UTF8);
                        Console.WriteLine("■ Encrypted file:\n{0}", sr.ReadToEnd());
                        sr.Close();
                    }
                }

                // Create a ICryptoTransform object to decrypt.
                ICryptoTransform decryptTransform = GTXSymmetricCrypt.CreateCryptoTransform(symAlg, false);
                if (GTXSymmetricCrypt.DecryptFile("Encrypted.txt", "Decrypted.txt", decryptTransform))
                {
                    using (FileStream fs = new FileStream("Decrypted.txt", FileMode.Open))
                    {
                        StreamReader sr = new StreamReader(fs, Encoding.UTF8);
                        Console.WriteLine("■ Decrypted file:\n{0}", sr.ReadToEnd());
                        sr.Close();
                    }
                }
            }
        }

        private static GTXKeyManager.SymmetricAlgTypes ReadSymmetricAlgType()
        {
            Console.WriteLine("Select the encrypt/decrypt algorithm: (Default is DES)");
            
            for (GTXKeyManager.SymmetricAlgTypes salTypeTemp = GTXKeyManager.SymmetricAlgTypes.DES;
                 salTypeTemp <= GTXKeyManager.SymmetricAlgTypes.RC2; ++salTypeTemp)
            {
                Console.WriteLine("{0} is {1}", (int)salTypeTemp, salTypeTemp.ToString());
            }

            // Read the symmetric algorithm command
            String algString = Console.ReadLine();
            GTXKeyManager.SymmetricAlgTypes salType = GTXKeyManager.SymmetricAlgTypes.DES;
            try
            {
                salType = (GTXKeyManager.SymmetricAlgTypes)Convert.ToInt32(algString);
                if (salType <= GTXKeyManager.SymmetricAlgTypes.DES &&
                    salType >= GTXKeyManager.SymmetricAlgTypes.TripleDES)
                {
                    salType = GTXKeyManager.SymmetricAlgTypes.DES;
                }
            }
            catch (System.Exception ex)
            {
                salType = GTXKeyManager.SymmetricAlgTypes.DES;
            }

            return salType;
        }
    }
}

The End...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: