c#实现文件加解密

using System;
using System.IO;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading;
using System.ComponentModel;

namespace aaa
{
     
class En_Dn
    
{
     
        
private Hashtable hs = new Hashtable();
        
private RijndaelManaged myRijndael;
        
private string Key = "";
        
private string IV = "~!#@$%HGF^&%&^hggk)KJKL989#er345(&*(HBh(u%g6HJ($jhWk7&!hg4ui%$hjk";
      
        
private string 解密(string files, int a)
        
{
            
try
            
{
                
int id = 0;
                hs.Clear();
                hs.Add(id
++, files);
                
string CPath = Path.GetDirectoryName(files);
                
string FileName = Path.GetFileName(files);

                myRijndael 
= new RijndaelManaged();

                
string inFileName = "";
                
foreach (System.Collections.DictionaryEntry de in this.hs)
                
{
                    inFileName 
= (string)de.Value;
                }

                FileStream fin 
= new FileStream(inFileName, FileMode.Open, FileAccess.Read);
                StreamReader sr 
= new StreamReader(fin);
                
char[] infolengthchar = new char[5];//文件的最后五个字符代表加密后的文件信息长度
                fin.Seek(-5, SeekOrigin.End);
                sr.Read(infolengthchar, 
05);
                
string infolengthstr = new string(infolengthchar);
                
int infolength = Convert.ToInt32(infolengthstr);//加密后的文件信息长度
                fin.Seek(-(5 + infolength), SeekOrigin.End);
                
char[] Filedatachar = new char[infolength];
                sr.Read(Filedatachar, 
0, infolength);
                
string Filedatastr = new string(Filedatachar);
                Filedatastr 
= this.Decrypt(Filedatastr);
                
int count = Convert.ToInt32(Filedatastr.Substring(Filedatastr.Length - 55));
                FileInfomation[] FI 
= new FileInfomation[count];
                
for (int i = 0; i < count; i++)
                
{
                    FI[i] 
= new FileInfomation();
                    
// FI[i].Filename = Filedatastr.Substring(i * 150, 100).TrimStart(new char[] { ' ' });
                    FI[i].Filename = "~" + Filedatastr.Substring(i * 150100).TrimStart(new char[] ' ' });
                    FI[i].Size 
= Convert.ToInt32(Filedatastr.Substring(i * 150 + 10050).TrimStart(new char[] ' ' }));
                }

                fin.Close();
                
//已得到该文件中包括的文件个数、文件名、长度。开始解密。
                long start = 0, currentlength = 0;

                
string outFileName = CPath + "\\" + FI[0].Filename;
                
for (int i = 0; i < count; i++)
                
{
                    outFileName 
= CPath + "\\" + FI[i].Filename;
                    File.Delete(outFileName);
                    currentlength 
= FI[i].Size;

                    fin 
= new FileStream(inFileName, FileMode.Open, FileAccess.Read);
                    FileStream fout 
= new FileStream(outFileName, FileMode.OpenOrCreate, FileAccess.Write);
                    fout.SetLength(
0);
                    fin.Seek(start, SeekOrigin.Begin);
                    
int cut = 100000;
                    
byte[] bin = new byte[cut];
                    
long rdlen = 0;
                    
long totlen = currentlength;
                    
int len;
                    myRijndael.Key 
= GetLegalKey();
                    myRijndael.IV 
= GetLegalIV();
                    ICryptoTransform encrypto 
= myRijndael.CreateDecryptor();
                    CryptoStream cs 
= new CryptoStream(fout, encrypto, CryptoStreamMode.Write);
                    
while (rdlen < totlen)
                    
{
                        
int report = (int)(((double)rdlen / totlen) * 1000);
                        
if (totlen - rdlen < cut)
                        
{
                            cut 
= (int)(totlen - rdlen);
                            rdlen 
= totlen;
                        }

                        len 
= fin.Read(bin, 0, cut);
                        cs.Write(bin, 
0, len);
                        rdlen 
= rdlen + len;
                    }

                    cs.Close();
                    cs.Dispose();

                    fout.Close();
                    fout.Dispose();

                    fin.Close();
                }


                fin.Dispose();

                
return outFileName;
            }

            
catch (Exception ex)
            
{
                
// MessageBox.Show("在文件解密的时候出现错误!错误提示: \n" + ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return "";
            }

        }

        
private string 解密(string files)
        
{
            
try
            
{
                
int id = 0;
                hs.Clear();
                hs.Add(id
++, files);
                
string pw = "";
                
string CPath = Path.GetDirectoryName(files);
                
//FileName = Path.GetFileNameWithoutExtension(this.files) + "~.tif";
                string FileName = Path.GetFileName(files);

                myRijndael 
= new RijndaelManaged();
                Key 
= pw;
                IV 
= "~!#@$%HGF^&%&^hggk)KJKL989#er345(&*(HBh(u%g6HJ($jhWk7&!hg4ui%$hjk";
                
//Directory.CreateDirectory(CPath + "\\已解密的文件");

                
string inFileName = "";
                
foreach (System.Collections.DictionaryEntry de in this.hs)
                
{
                    inFileName 
= (string)de.Value;
                }

                FileStream fin 
= new FileStream(inFileName, FileMode.Open, FileAccess.Read);
                StreamReader sr 
= new StreamReader(fin);
                
char[] infolengthchar = new char[5];//文件的最后五个字符代表加密后的文件信息长度
                fin.Seek(-5, SeekOrigin.End);
                sr.Read(infolengthchar, 
05);
                
string infolengthstr = new string(infolengthchar);
                
int infolength = Convert.ToInt32(infolengthstr);//加密后的文件信息长度
                fin.Seek(-(5 + infolength), SeekOrigin.End);
                
char[] Filedatachar = new char[infolength];
                sr.Read(Filedatachar, 
0, infolength);
                
string Filedatastr = new string(Filedatachar);
                Filedatastr 
= this.Decrypt(Filedatastr);
                
int count = Convert.ToInt32(Filedatastr.Substring(Filedatastr.Length - 55));
                FileInfomation[] FI 
= new FileInfomation[count];
                
for (int i = 0; i < count; i++)
                
{
                    FI[i] 
= new FileInfomation();
                    
//FI[i].Filename = Filedatastr.Substring(i * 150, 100).TrimStart(new char[] { ' ' });
                    FI[i].Filename = "~" + Filedatastr.Substring(i * 150100).TrimStart(new char[] ' ' });
                    FI[i].Size 
= Convert.ToInt32(Filedatastr.Substring(i * 150 + 10050).TrimStart(new char[] ' ' }));
                }

                fin.Close();
                
//已得到该文件中包括的文件个数、文件名、长度。开始解密。
                long start = 0, currentlength = 0;
                
string outFileName = "";
                
for (int i = 0; i < count; i++)
                
{
                    
//string outFileName = CPath + @"\已解密的文件\" + FI[i].Filename;
                    outFileName = CPath + "\\" + FI[i].Filename;
                    File.Delete(outFileName);
                    currentlength 
= FI[i].Size;

                    fin 
= new FileStream(inFileName, FileMode.Open, FileAccess.Read);
                    FileStream fout 
= new FileStream(outFileName, FileMode.OpenOrCreate, FileAccess.Write);
                    fout.SetLength(
0);
                    fin.Seek(start, SeekOrigin.Begin);
                    
int cut = 100000;
                    
byte[] bin = new byte[cut];
                    
long rdlen = 0;
                    
long totlen = currentlength;
                    
int len;
                    myRijndael.Key 
= GetLegalKey();
                    myRijndael.IV 
= GetLegalIV();
                    ICryptoTransform encrypto 
= myRijndael.CreateDecryptor();
                    CryptoStream cs 
= new CryptoStream(fout, encrypto, CryptoStreamMode.Write);
                    
while (rdlen < totlen)
                    
{
                        
if (totlen - rdlen < cut)
                        
{
                            cut 
= (int)(totlen - rdlen);
                            rdlen 
= totlen;
                        }

                        len 
= fin.Read(bin, 0, cut);
                        cs.Write(bin, 
0, len);
                        rdlen 
= rdlen + len;
                    }

                    cs.Close();
                    fout.Close();
                    fin.Close();
                }

                
return outFileName;
            }

            
catch (Exception ex)
            
{
                MessageBox.Show(
"在文件解密的时候出现错误!错误提示: \n" + ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                
return "";
            }

        }


        
private void 加密(string files, string newname)
        
{
            
try
            
{
                
int id = 0;
                hs.Clear();
                hs.Add(id
++, files);
                
string pw = "";
                
string CPath = Path.GetDirectoryName(files);
                
//string FileName = "~" + Path.GetFileName(files);
                myRijndael = new RijndaelManaged();
                Key 
= pw;
                IV 
= "~!#@$%HGF^&%&^hggk)KJKL989#er345(&*(HBh(u%g6HJ($jhWk7&!hg4ui%$hjk";
                
string outFileName = newname;

                
string Filedata = "";//文件名(100字节)长度(50)个数(5)前补空格 加密后 长度(5)
                int count = 0;
                
long curlength = -16;//这里是负16,我也不知道是为什么,第一次读fout长度时会少16,以后再读都正常
                foreach (System.Collections.DictionaryEntry de in this.hs)
                
{
                    FileStream fout 
= new FileStream(outFileName, FileMode.Append, FileAccess.Write);
                    FileStream fin 
= new FileStream((string)de.Value, FileMode.Open, FileAccess.Read);
                    myRijndael.Key 
= GetLegalKey();
                    myRijndael.IV 
= GetLegalIV();

                    
byte[] bin = new byte[100000];
                    
long rdlen = 0;
                    
long totlen = fin.Length;
                    
int len;

                    ICryptoTransform encrypto 
= myRijndael.CreateEncryptor();
                    CryptoStream cs 
= new CryptoStream(fout, encrypto, CryptoStreamMode.Write);
                    
while (rdlen < totlen)
                    
{
                        len 
= fin.Read(bin, 0100000);
                        cs.Write(bin, 
0, len);
                        rdlen 
= rdlen + len;
                    }

                    
long foutlenth = fout.Length;
                    Filedata 
+= Path.GetFileName((string)de.Value).PadLeft(100' '+ (foutlenth - curlength).ToString().PadLeft(50' ');
                    curlength 
= foutlenth;
                    count
++;
                    cs.Close();
                    fout.Close();
                    fin.Close();
                }

                Filedata 
+= count.ToString().PadLeft(5'0');
                Filedata 
= this.Encrypt(Filedata);
                Filedata 
+= Filedata.Length.ToString().PadLeft(5'0');
                FileStream f 
= new FileStream(outFileName, FileMode.Append, FileAccess.Write);
                StreamWriter sw 
= new StreamWriter(f);
                sw.Write(Filedata);
                sw.Close();
                f.Close();

                File.Delete(files);
            }

            
catch (Exception ex)
            
{
                MessageBox.Show(
"在文件加密的时候出现错误!错误提示: \n" + ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }



        
/// <summary>
        
/// 获得密钥
        
/// </summary>
        
/// <returns>密钥</returns>

        private byte[] GetLegalKey()
        
{
            
string sTemp = Key;
            myRijndael.GenerateKey();
            
byte[] bytTemp = myRijndael.Key;
            
int KeyLength = bytTemp.Length;
            
if (sTemp.Length > KeyLength)
                sTemp 
= sTemp.Substring(0, KeyLength);
            
else if (sTemp.Length < KeyLength)
                sTemp 
= sTemp.PadRight(KeyLength, ' ');
            
return System.Text.ASCIIEncoding.ASCII.GetBytes(sTemp);
        }

        
/// <summary>
        
/// 获得初始向量IV
        
/// </summary>
        
/// <returns>初试向量IV</returns>

        private byte[] GetLegalIV()
        
{
            
string sTemp = IV;
            myRijndael.GenerateIV();
            
byte[] bytTemp = myRijndael.IV;
            
int IVLength = bytTemp.Length;
            
if (sTemp.Length > IVLength)
                sTemp 
= sTemp.Substring(0, IVLength);
            
else if (sTemp.Length < IVLength)
                sTemp 
= sTemp.PadRight(IVLength, ' ');
            
return System.Text.ASCIIEncoding.ASCII.GetBytes(sTemp);
        }

        
/// <summary>
        
/// 加密方法
        
/// </summary>
        
/// <param name="Source">待加密的串</param>
        
/// <returns>经过加密的串</returns>

        public string Encrypt(string Source)
        
{
            
try
            
{
                
byte[] bytIn = System.Text.UTF8Encoding.UTF8.GetBytes(Source);
                MemoryStream ms 
= new MemoryStream();
                myRijndael.Key 
= GetLegalKey();
                myRijndael.IV 
= GetLegalIV();
                ICryptoTransform encrypto 
= myRijndael.CreateEncryptor();
                CryptoStream cs 
= new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
                cs.Write(bytIn, 
0, bytIn.Length);
                cs.FlushFinalBlock();
                ms.Close();
                
byte[] bytOut = ms.ToArray();
                
return Convert.ToBase64String(bytOut);
            }

            
catch (Exception ex)
            
{
                
throw new Exception("在文件加密的时候出现错误!错误提示: \n" + ex.Message);
            }

        }

        
/// <summary>
        
/// 解密方法
        
/// </summary>
        
/// <param name="Source">待解密的串</param>
        
/// <returns>经过解密的串</returns>

        public string Decrypt(string Source)
        
{
            
try
            
{
                
byte[] bytIn = Convert.FromBase64String(Source);
                MemoryStream ms 
= new MemoryStream(bytIn, 0, bytIn.Length);
                myRijndael.Key 
= GetLegalKey();
                myRijndael.IV 
= GetLegalIV();
                ICryptoTransform encrypto 
= myRijndael.CreateDecryptor();
                CryptoStream cs 
= new CryptoStream(ms, encrypto, CryptoStreamMode.Read);
                StreamReader sr 
= new StreamReader(cs);
                
return sr.ReadToEnd();
            }

            
catch (Exception ex)
            
{
                
throw new Exception("在文件解密的时候出现错误!错误提示: \n" + ex.Message);
            }

        }

     
    }

}

原文地址:https://www.cnblogs.com/dreign/p/751093.html