FileEncryptTool.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using Y.Utils.DataUtils.EncryptUtils;
  7. namespace Y.Utils.IOUtils.FileUtils
  8. {
  9. public class FileEncryptTool
  10. {
  11. private static int AESKeyLength = 32;//AES加密的密码为32位
  12. private static char AESFillChar = 'Y';//AES密码填充字符
  13. private static string FileTypeDesc = "Oreo.FileMan.EncryptFile";
  14. private static int FileHeadLength = 128;
  15. private static int FileBuffer = 1024 * 1024;
  16. /// <summary>
  17. /// 文件加密
  18. /// </summary>
  19. /// <param name="srcFile"></param>
  20. /// <param name="dstFile"></param>
  21. /// <param name="password"></param>
  22. /// <returns></returns>
  23. public static bool Encrypt(string srcFile, string dstFile, string password)
  24. {
  25. string fmtPwd = FmtPassword(password);
  26. string pwdMd5 = MD5Tool.Encrypt(fmtPwd);
  27. //检测文件存在
  28. if (File.Exists(srcFile) && !File.Exists(dstFile))
  29. {
  30. string md5 = FileTool.GetMD5(srcFile);
  31. using (FileStream fsRead = new FileStream(srcFile, FileMode.Open))
  32. {
  33. using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create))
  34. {
  35. try
  36. {
  37. //文件头部数据定义
  38. List<byte[]> headdata = new List<byte[]>()
  39. {
  40. Encoding.Default.GetBytes(FileTypeDesc),
  41. Encoding.Default.GetBytes(md5),
  42. Encoding.Default.GetBytes(fmtPwd),
  43. Encoding.Default.GetBytes(pwdMd5)
  44. };
  45. //写入长度
  46. for (int i = 0; i < FileHeadLength; i++)
  47. {
  48. if (headdata.Count > i)
  49. {
  50. byte[] length = BitConverter.GetBytes(headdata[i].Length);
  51. fsWrite.Write(length, 0, length.Length);
  52. }
  53. else
  54. {
  55. byte[] length = BitConverter.GetBytes(0);
  56. fsWrite.Write(length, 0, length.Length);
  57. }
  58. }
  59. //写入数据
  60. for (int i = 0; i < headdata.Count; i++)
  61. {
  62. fsWrite.Write(headdata[i], 0, headdata[i].Length);
  63. }
  64. //设置文件头部信息
  65. //byte[] typeByte = Encoding.Default.GetBytes(FileTypeDesc);
  66. //byte[] md5Byte = Encoding.Default.GetBytes(md5);
  67. //byte[] pwdByte = Encoding.Default.GetBytes(fmtPwd);
  68. //byte[] pwdMd5Byte = Encoding.Default.GetBytes(pwdMd5);
  69. //设置文件头部数据长度信息
  70. //long[] headpart = new long[FileHeadLength];
  71. //headpart[0] = typeByte.Length;
  72. //headpart[1] = md5Byte.Length;
  73. //headpart[2] = pwdByte.Length;
  74. //headpart[3] = pwdMd5Byte.Length;
  75. //写入头部长度信息
  76. //foreach (var h in headpart)
  77. //{
  78. // byte[] temp = BitConverter.GetBytes(h);
  79. // fsWrite.Write(temp, 0, temp.Length);
  80. //}
  81. //写入文件头部信息
  82. //fsWrite.Write(typeByte, 0, typeByte.Length);
  83. //fsWrite.Write(md5Byte, 0, md5Byte.Length);
  84. //fsWrite.Write(pwdByte, 0, pwdByte.Length);
  85. //fsWrite.Write(pwdMd5Byte, 0, pwdMd5Byte.Length);
  86. //写入文件源数据
  87. int readCount = 0;
  88. byte[] buffer = new byte[FileBuffer];
  89. while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0)
  90. {
  91. if (readCount != buffer.Length)
  92. {
  93. byte[] temp = new byte[readCount];
  94. Buffer.BlockCopy(buffer, 0, temp, 0, readCount);
  95. byte[] enbyte = AesTool.Encrypt(temp, fmtPwd);
  96. fsWrite.Write(enbyte, 0, enbyte.Length);
  97. }
  98. else
  99. {
  100. byte[] enbyte = AesTool.Encrypt(buffer, fmtPwd);
  101. fsWrite.Write(enbyte, 0, enbyte.Length);
  102. }
  103. }
  104. return true;
  105. }
  106. catch { }
  107. }
  108. }
  109. //加密失败后,删除加密的文件
  110. try { File.Delete(dstFile); } catch { }
  111. }
  112. return false;
  113. }
  114. /// <summary>
  115. /// 文件解密
  116. /// </summary>
  117. /// <param name="srcFile"></param>
  118. /// <param name="dstFile"></param>
  119. /// <param name="password"></param>
  120. /// <returns></returns>
  121. public static bool Decrypt(string srcFile, string dstFile, string password)
  122. {
  123. string fmtPwd = FmtPassword(password);
  124. string pwdMd5 = MD5Tool.Encrypt(fmtPwd);
  125. //检测文件存在
  126. if (File.Exists(srcFile) && !File.Exists(dstFile))
  127. {
  128. string[] fileInfo = new string[FileHeadLength];
  129. using (FileStream fsRead = new FileStream(srcFile, FileMode.Open))
  130. {
  131. using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create))
  132. {
  133. try
  134. {
  135. List<byte[]> headdata = new List<byte[]>();
  136. for()
  137. byte[] headpart = new byte[8 * FileHeadLength];//fmk文件头
  138. long[] dataLong = new long[FileHeadLength];//信息长度
  139. if (fsRead.Read(headpart, 0, headpart.Length) == headpart.Length)
  140. {
  141. //读取信息长度
  142. for (int i = 0; i < dataLong.Length; i++)
  143. {
  144. dataLong[i] = BitConverter.ToInt64(headpart, i * 8);
  145. }
  146. byte[] typeByte = new byte[dataLong[0]];
  147. byte[] md5Byte = new byte[dataLong[1]];
  148. byte[] pwdByte = new byte[dataLong[2]];
  149. byte[] pwdMd5Byte = new byte[dataLong[3]];
  150. fsRead.Read(typeByte, 0, typeByte.Length);
  151. fsRead.Read(md5Byte, 0, md5Byte.Length);
  152. fsRead.Read(pwdByte, 0, pwdByte.Length);
  153. fsRead.Read(pwdMd5Byte, 0, pwdMd5Byte.Length);
  154. fileInfo[0] = Encoding.Default.GetString(typeByte);
  155. fileInfo[1] = Encoding.Default.GetString(md5Byte);
  156. fileInfo[2] = Encoding.Default.GetString(pwdByte);
  157. fileInfo[3] = Encoding.Default.GetString(pwdMd5Byte);
  158. }
  159. if (pwdMd5 == fileInfo[3])
  160. {
  161. int readCount = 0;
  162. byte[] buffer = new byte[FileBuffer + 16];
  163. while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0)
  164. {
  165. if (readCount != buffer.Length)
  166. {
  167. byte[] temp = new byte[readCount];
  168. Buffer.BlockCopy(buffer, 0, temp, 0, readCount);
  169. byte[] debyte = AesTool.Decrypt(temp, fmtPwd);
  170. fsWrite.Write(debyte, 0, debyte.Length);
  171. }
  172. else
  173. {
  174. byte[] debyte = AesTool.Decrypt(buffer, fmtPwd);
  175. fsWrite.Write(debyte, 0, debyte.Length);
  176. }
  177. }
  178. }
  179. }
  180. catch { }
  181. }
  182. }
  183. string md5 = FileTool.GetMD5(dstFile);
  184. if (md5 == fileInfo[1])
  185. {
  186. return true;
  187. }
  188. else
  189. {
  190. //解密失败后,删除解密的文件
  191. try { File.Delete(dstFile); } catch { }
  192. }
  193. }
  194. return false;
  195. }
  196. /// <summary>
  197. /// 格式化密码
  198. /// </summary>
  199. /// <param name="s">要格式化的密码</param>
  200. /// <returns></returns>
  201. private static string FmtPassword(string s)
  202. {
  203. string password = s ?? "";
  204. //格式化密码
  205. if (password.Length < AESKeyLength)
  206. {
  207. //补足不够长的密码
  208. password = password + new string(AESFillChar, AESKeyLength - password.Length);
  209. }
  210. else if (password.Length > AESKeyLength)
  211. {
  212. //截取过长的密码
  213. password = password.Substring(0, AESKeyLength);
  214. }
  215. return password;
  216. }
  217. }
  218. }