好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Windows中使用C#为文件夹和文件编写密码锁的示例分享

c#文件夹加锁小工具
用c#语言实现一个文件夹锁的程序,网上类似的[xxx文件夹xxx]软件很多,但是基本上都是c/c++语言实现的,且都没有提供源码(这个可以理解,毕竟是加密程序,不应该泄露源码)。

程序的基本原理是:用c#语言重命名文件夹,通过重命名使之成为windows安全文件的类标识符。具体的方法是为文件夹添加拓展名[.{2559a1f2-21d7-11d4-bdaf-00c04f60b9f0}]

(.{2559a1f2-21d7-11d4-bdaf-00c04f60b9f0}是windows安全文件的类标识符),这时文件夹的图标就会变成一把锁,这样文件夹就被加锁了。

程序的主界面非常简洁,截图如下:

程序中加密解密文件夹的核心代码如下:

?

private void btnbrowsefolder_click( object sender, eventargs e)

{

  

   status = locktype; //

  

 

   if (folderbrowserdialog1.showdialog() == dialogresult.ok)

   {

     directoryinfo d = new directoryinfo(folderbrowserdialog1.selectedpath);

     string selectedpath = d.parent.fullname + d.name;

     if (folderbrowserdialog1.selectedpath.lastindexof( ".{" ) == -1) //通过文件夹名称,判断加密

     {         

       setpwd(folderbrowserdialog1.selectedpath);

       if (!d.root.equals(d.parent.fullname))

       {           

           d.moveto(d.parent.fullname + "\\" + d.name + status); //文件夹重命名

       }

       else d.moveto(d.parent.fullname + d.name + status);

       txtfolderpath.text = folderbrowserdialog1.selectedpath;

      

     }

     else //解密文件夹

     {

       status = getstatus(status);

       bool s = checkpwd();

       if (s)

       {

         file.delete(folderbrowserdialog1.selectedpath + "\\key.xml" );

         string path = folderbrowserdialog1.selectedpath.substring(0, folderbrowserdialog1.selectedpath.lastindexof( "." ));

         d.moveto(path);

         txtfolderpath.text = path;

        

       }

     }

   }

}

程序的运行效果如下:

以加密d盘下面的test文件夹为例,结果如下:

首先通过folderbrowserdialog选择相应的文件夹

输入密码,加锁

效果如下:

此时双击文件夹已经无法打开。

选择加密后的test文件夹,输入加密时输入的密码,可解锁。

test文件夹已经解密

 

加密解密文件小工具

上面分享了一个文件夹加密小工具,该工具是操作文件夹名称的方法实现文件夹的一般加密,文件夹中的文件(视频、图片等)都原封不动的保存在那里。

在网上搜索相关文件加密的程序,发现给出的基本都是针对[字符创]、[文本]的加密与解密。对视频文件、图片等一般文件的加密解密程序少之又少,所以我们下面再来实现一个对一般文件进行加密的小工具。

程序的主要功能是:用户通过文件选择框选择要加密的文件-》输入密码进行加密;选择加密后的文件,输入密码进行解密。

程序的主界面如下:

三个按钮的click事件处理程序如下:

?

     private void btnselectfile_click(object sender, eventargs e)

     {

       if (openfiledialog1.showdialog() == system.windows.forms.dialogresult.ok)

       {

         txtfilename.text = openfiledialog1.filename ;

       }

     }

 

     private void btnencryptfile_click(object sender, eventargs e)

     {

       string infile=txtfilename.text;

       string outfile = infile + ".dat" ;

       string password=txtpassword.text ;

       desfile.desfileclass.encryptfile(infile, outfile, password); //加密文件

       //删除加密前的文件

       file.delete(infile);

       txtfilename.text = string.empty;

       messagebox.show( "加密成功" );

     }

 

     private void btndecryptfile_click(object sender, eventargs e)

     {

       string infile = txtfilename.text;

       string outfile = infile.substring( 0 ,infile.length - 4 );

       string password = txtpassword.text;

       desfile.desfileclass.decryptfile (infile, outfile, password); //解密文件

       //删除解密前的文件

       file.delete(infile);

       txtfilename.text = string.empty;

       messagebox.show( "解密成功" );

     }

 

加密解密的help文件源码如下:

 

using system;

using system.collections.generic;

using system.text;

using system.security.cryptography;

using system.io;

 

namespace desfile

{

   /// <summary>

   /// 异常处理类

   /// </summary>

   public class cryptohelpexception : applicationexception

   {

     public cryptohelpexception(string msg) : base(msg) { }

   }

 

   /// <summary>

   /// crypthelp

   /// </summary>

   public class desfileclass

   {

     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>

     /// 创建debuglzq ,http://HdhCmsTestcnblogs测试数据/debuglzq

     /// </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 = desfileclass.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 = desfileclass.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( "文件大小不匹配" );

       }

     }

   }

}

加密/解密结果:

以加密d盘下的1.avi为例,加密后的文件为1.avi.dat,即使重命名回1.avi文件依然无法打开(文件被加密)。

输入密码进行解密后,文件恢复解密,可以顺利打开~

dy("nrwz");

查看更多关于Windows中使用C#为文件夹和文件编写密码锁的示例分享的详细内容...

  阅读:43次