设为首页
加入收藏
联系我们
首页 基础教程 技术文档 实例分析 数 据 库 疑难杂症 ASP.NET 七夕许愿树 技术论坛
最新文章
  .NET上传图片加文字…
 在vs.net bate…
 C#中利用正则表达式实现…
 Visual C#的SQ…
 关于使用存储过程创建分页
 通用分页显示查询存储过程
 大数据量的分页
 什么是web.confi…
 ASP.NET 配置文件…
 对“三层结构”的深入理解…
 多个关键字的查询问题
 VB和C# 语法对比图 …
 C#基础全接触
 用C#压缩和修复Acce…
 C#中的类型相等与恒等(…
推荐文章
 关于C#中的REF和黓认…
 读书笔记c#高级编程 委…
 【算法】C#快速排序类
 Visual C#的SQ…
 C#中调用API
 Infragistics…
 C#接口转换
 C#读取设备信息
 用.net操作word
 C# MessageBo…
 Visual C#中的数…
 雅虎公司C#笔试题,看看…
 C#.NET使用NHib…
 .net学习之运算符重载…
 Visual C# 3.…
热门文章
 ADO.Net与ADO在…
 开发ASP.NET下的M…
 用C#+XMI技术进行U…
 什么是虚拟机?
 C#基础全接触
 C#中利用正则表达式实现…
 雅虎公司C#笔试题,看看…
 用Visual C# 2…
 C#学习第一天
 C#语言初级入门(1)
 VB和C# 语法对比图 …
 远程重启计算机(C#)
 什么是B/S三层?
 Visual C#的SQ…
 Visual C#常用函…
.NET下对二进制文件进行加密解密(C#)
阅读正文 文字大小:增大 减小  文字行距:增大 减小   双击自动滚屏
本文由中国C#技术学习中心整理  如果你对本文有不明之处请到技术论坛讨论!

下面的类实现了文件的加密和解密操作,试验了几种文件类型均没有问题,现在和大家共享一下.
namespace MyCryptoHelp
{
    /// <summary>
    /// 异常处理类
    /// </summary>
    public class CryptoHelpException : ApplicationException
    {
        public CryptoHelpException( string msg ):base( msg )
        {
        }
    }
   
    /// <summary>
    /// CryptHelp
    /// </summary>
    public class CryptoHelp
    {
        private const ulong FC_TAG = 0xFC010203040506CF;
       
        private const
        int BUFFER_SIZE = 128*1024;
       
        /// <summary> 
        /// 检验两个Byte数组是否相同 
        /// </summary> 
        /// <param name="b1">Byte数组</param> 
        /// <param name="b2">Byte数组</param> 
        /// <returns>true-相等</returns> 
        private static bool CheckByteArrays( byte[] b1, byte[] b2 ) 
        {
            if( b1.Length == b2.Length )
            {
                for( int i = 0;
                i < b1.Length;
                ++i )
                {
                    if( b1[i] != b2[i] )
                    return false;
                }
                return true;
            }
            return false;
        }
       
        /// <summary> 
        /// 创建Rijndael SymmetricAlgorithm 
        /// </summary> 
        /// <param name="password">密码</param> 
        /// <param name="salt"></param> 
        /// <returns>加密对象</returns> 
        private static SymmetricAlgorithm CreateRijndael( string password, byte[] salt ) 
        {
            PasswordDeriveBytes pdb = new PasswordDeriveBytes( password,salt,"SHA256",1000 );
            SymmetricAlgorithm sma = Rijndael.Create( );
            sma.KeySize = 256;
            sma.Key = pdb.GetBytes( 32 );
            sma.Padding = PaddingMode.PKCS7;
            return sma;
        }
       
        /// <summary> 
        /// 加密文件随机数生成 
        /// </summary> 
        private static RandomNumberGenerator rand = new RNGCryptoServiceProvider( );
       
        /// <summary> 
        /// 生成指定长度的随机Byte数组 
        /// </summary> 
        /// <param name="count">Byte数组长度</param> 
        /// <returns>随机Byte数组</returns> 
        private static byte[] GenerateRandomBytes( int count ) 
        {
            byte[] bytes = new byte[count];
            rand.GetBytes( bytes );
            return bytes;
        }
       
        /// <summary> 
        /// 加密文件 
        /// </summary> 
        /// <param name="inFile">待加密文件</param> 
        /// <param name="outFile">加密后输入文件</param> 
        /// <param name="password">加密密码</param> 
        public static void EncryptFile( string inFile,
        string outFile,
        string password ) 
        {
            using( FileStream fin = File.OpenRead( inFile ),
            fout = File.OpenWrite( outFile ) )
            {
                long lSize = fin.Length;
                // 输入文件长度
                int size = ( int )lSize;
                byte[] bytes = new byte[BUFFER_SIZE];
                // 缓存
                int read = -1;
                // 输入文件读取数量
                int value = 0;
                // 获取IV和salt
                byte[] IV = GenerateRandomBytes( 16 );
                byte[] salt = GenerateRandomBytes( 16 );
                // 创建加密对象
                SymmetricAlgorithm sma = CryptoHelp.CreateRijndael( password, salt );
                sma.IV = IV;
                // 在输出文件开始部分写入IV和salt
                fout.Write( IV,0,IV.Length );
                fout.Write( salt,0,salt.Length );
                // 创建散列加密
                HashAlgorithm hasher = SHA256.Create( );
                using( CryptoStream cout = new CryptoStream( fout,sma.CreateEncryptor( ),CryptoStreamMode.Write ),
                chash = new CryptoStream( Stream.Null,hasher,CryptoStreamMode.Write ) )
                {
                    BinaryWriter bw = new BinaryWriter( cout );
                    bw.Write( lSize );
                    bw.Write( FC_TAG );
                    // 读写字节块到加密流缓冲区
                    while(( read = fin.Read( bytes,0,bytes.Length ) ) != 0)
                    {
                        cout.Write( bytes,0,read );
                        chash.Write( bytes,0,read );
                        value += read;
                    }
                    // 关闭加密流
                    chash.Flush( );
                    chash.Close( );
                    // 读取散列
                    byte[] hash = hasher.Hash;
                    // 输入文件写入散列
                    cout.Write( hash,0,hash.Length );
                    // 关闭文件流
                    cout.Flush( );
                    cout.Close( );
                }
            }
        }
       
        /// <summary> 
        /// 解密文件 
        /// </summary> 
        /// <param name="inFile">待解密文件</param> 
        /// <param name="outFile">解密后输出文件</param> 
        /// <param name="password">解密密码</param> 
        public static void DecryptFile( string inFile,
        string outFile,
        string password ) 
        {
            // 创建打开文件流
            using( FileStream fin = File.OpenRead( inFile ),
            fout = File.OpenWrite( outFile ) )
            {
                int size = ( int )fin.Length;
                byte[] bytes = new byte[BUFFER_SIZE];
               
                int read = -1;
               
                int value = 0;
               
                int outValue = 0;
                byte[] IV = new byte[16];
                fin.Read( IV,0,16 );
                byte[] salt = new byte[16];
                fin.Read( salt,0,16 );
                SymmetricAlgorithm sma = CryptoHelp.CreateRijndael( password,salt );
                sma.IV = IV;
                value = 32;
                long lSize = -1;
                // 创建散列对象, 校验文件
                HashAlgorithm hasher = SHA256.Create( );
                using( CryptoStream cin = new CryptoStream( fin,sma.CreateDecryptor( ),CryptoStreamMode.Read ),
                chash = new CryptoStream( Stream.Null,hasher,CryptoStreamMode.Write ) )
                {
                    // 读取文件长度
                    BinaryReader br = new BinaryReader( cin );
                    lSize = br.ReadInt64( );
                    ulong tag = br.ReadUInt64( );
                    if( FC_TAG != tag )
                    throw new CryptoHelpException( "文件被破坏" );
                    long numReads = lSize / BUFFER_SIZE;
                    long slack = ( long )lSize % BUFFER_SIZE;
                    for( int i = 0;
                    i < numReads;
                    ++i )
                    {
                        read = cin.Read( bytes,0,bytes.Length );
                        fout.Write( bytes,0,read );
                        chash.Write( bytes,0,read );
                        value += read;
                        outValue += read;
                    }
                    if( slack > 0 )
                    {
                        read = cin.Read( bytes,0,( int )slack );
                        fout.Write( bytes,0,read );
                        chash.Write( bytes,0,read );
                        value += read;
                        outValue += read;
                    }
                    chash.Flush( );
                    chash.Close( );
                    fout.Flush( );
                    fout.Close( );
                    byte[] curHash = hasher.Hash;
                    // 获取比较和旧的散列对象
                    byte[] oldHash = new byte[hasher.HashSize / 8];
                    read = cin.Read( oldHash,0,oldHash.Length );
                    if( ( oldHash.Length != read ) || ( !CheckByteArrays( oldHash,curHash ) ) )
                    throw new CryptoHelpException( "文件被破坏" );
                }
                if( outValue != lSize )
                throw new CryptoHelpException( "文件大小不匹配" );
            }
        }
    }
}

// 调用
public class TestClass
{
    string myPassword = "TEST_PASSWORD_~!@#";
   
    string myPlainFile = "test.txt";
   
    string myEncryptedFile = "test.encrypted";
   
    string myDecryptedFile = "test.decrypted";
    [STAThread]
    static void Main( )
    {
        CryptoHelp.EncryptFile( myPlainFile, myEncryptedFile, myPassword );
        CryptoHelp.DecryptFile( myEncryptedFile,myDecryptedFile, myPassword );
    }
}

本文由中国C#技术学习中心整理  如果你对本文有不明之处请到技术论坛讨论!

中国C#技术交流QQ群:6337034  10976424  9383681  35248582  35248645
版权所有:中国C#技术学习中心 Copyright © 20010-20012
建议浏览分辨率使用:1024*768分辨率
粤ICP备05002251号