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, 0, 5); 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 - 5, 5)); 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 * 150, 100).TrimStart(new char[] { ' ' }); FI[i].Size = Convert.ToInt32(Filedatastr.Substring(i * 150 + 100, 50).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, 0, 5); 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 - 5, 5)); 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 * 150, 100).TrimStart(new char[] { ' ' }); FI[i].Size = Convert.ToInt32(Filedatastr.Substring(i * 150 + 100, 50).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, 0, 100000); 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); } } } }