/// <summary> /// 解密文件 /// </summary> public static void DecryptFile(string path, string pwd, RefreshFileProgress refreshFileProgress) { try { if (File.Exists(path + tempFileExt)) { File.Delete(path + tempFileExt); } using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { if (fs.Length > 0) { using (FileStream fsnew = new FileStream(path + tempFileExt, FileMode.OpenOrCreate, FileAccess.Write)) { if (File.Exists(path + tempFileExt)) { File.SetAttributes(path + tempFileExt, FileAttributes.Hidden); } int blockCount = ((int)fs.Length - 1) / decryptSize + 1; for (int i = 0; i < blockCount; i++) { int size = decryptSize; if (i == blockCount - 1) { size = (int)(fs.Length - i * decryptSize); } byte[] bArr = new byte[size]; fs.Read(bArr, 0, size); byte[] result = AES.AESDecrypt(bArr, pwd); fsnew.Write(result, 0, result.Length); fsnew.Flush(); refreshFileProgress(blockCount, i + 1); //更新进度 } fsnew.Close(); fsnew.Dispose(); } fs.Close(); fs.Dispose(); FileAttributes fileAttr = File.GetAttributes(path); File.SetAttributes(path, FileAttributes.Archive); File.Delete(path); //File.Move(path + tempFileExt, path); //用下面的两句替代/ File.Copy(path + tempFileExt, path); File.Delete(path + tempFileExt); File.SetAttributes(path, fileAttr); } } } catch (Exception ex) { if (File.Exists(path + tempFileExt)) { File.Delete(path + tempFileExt); } throw ex; } }
/// <summary> /// 解密当前文件夹 /// </summary> public static void DecryptCurrentDirectory(string dirPath, string pwd, RefreshDirProgress refreshDirProgress, RefreshFileProgress refreshFileProgress) { int delta = 0; string[] filePaths = Directory.GetFiles(dirPath, "*"); for (int i = 0; i < filePaths.Length; i++) { if (!File.Exists(filePaths[i])) { continue; } if (IsSelf(filePaths[i])) { delta = -1; continue; } FileEncrypt.DecryptFile(filePaths[i], pwd, refreshFileProgress); refreshDirProgress(filePaths.Length - 1, i + 1 + delta); } }
/// <summary> /// 解密文件夹及其子文件夹中的所有文件 /// </summary> public static void DecryptDirectory(string dirPath, string pwd, RefreshDirProgress refreshDirProgress, RefreshFileProgress refreshFileProgress) { string[] filePaths = Directory.GetFiles(dirPath, "*"); for (int i = 0; i < filePaths.Length; i++) { if (!File.Exists(filePaths[i])) { continue; } FileEncrypt.DecryptFile(filePaths[i], pwd, refreshFileProgress); refreshDirProgress(filePaths.Length, i + 1); } }
/// <summary> /// 解密文件夹及其子文件夹中的所有文件 /// </summary> public static void DecryptDirectory(string dirPath, string pwd, RefreshDirProgress refreshDirProgress, RefreshFileProgress refreshFileProgress) { string[] filePaths = Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories); for (int i = 0; i < filePaths.Length; i++) { FileEncrypt.DecryptFile(filePaths[i], pwd, refreshFileProgress); refreshDirProgress(filePaths.Length, i + 1); } }
//private static void CheckVolume(string targetPath, byte[] result, int volumnSize,string extension,bool coverExisted ref string encryptedFileName, ref int fileCount, ref FileStream fsnew, ref long currentSize) //{ //} public static FileInfo[] DecryptFile(this RijndaelManaged manager, string sourcePath, string targetPath, int bufferLength = 1024 * 1024, string suffix = null, bool coverExistedFile = false, RefreshFileProgress refreshFileProgress = null) { string target = targetPath.RemoveEnd(suffix); CheckFileAndDirectoryExist(target, coverExistedFile); List <string> encryptedFileNames = new List <string>() { sourcePath }; var lastencryptedFile = sourcePath; try { int fileCount = 0; while (File.Exists(sourcePath + (++fileCount))) { encryptedFileNames.Add(sourcePath + fileCount); lastencryptedFile = sourcePath + fileCount; } using (FileStream streamTarget = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write)) { using (var decryptor = manager.CreateDecryptor()) { foreach (var encryptedFileName in encryptedFileNames) { FileStream streamSource = new FileStream(encryptedFileName, FileMode.Open, FileAccess.Read); long currentSize = 0; int size; byte[] input = new byte[bufferLength]; byte[] output = new byte[bufferLength]; long fileLength = streamSource.Length; while ((size = streamSource.Read(input, 0, input.Length)) != 0) { int outputSize = 0; if (streamSource.Position == fileLength && encryptedFileName == lastencryptedFile) { outputSize = (output = decryptor.TransformFinalBlock(input, 0, size)).Length; } else { outputSize = decryptor.TransformBlock(input, 0, size, output, 0); } currentSize += output.Length; streamTarget.Write(output, 0, outputSize); streamTarget.Flush(); refreshFileProgress?.Invoke(sourcePath, encryptedFileName, fileLength, currentSize); //更新进度 } streamSource.Close(); streamSource.Dispose(); } } streamTarget.Close(); streamTarget.Dispose(); } new FileInfo(target).Attributes = File.GetAttributes(sourcePath); return(encryptedFileNames.Select(p => new FileInfo(p)).ToArray()); } catch (Exception ex) { HandleException(target, ex); return(null); } }
/// <summary> /// 加密文件 /// </summary> /// <param name="manager"></param> /// <param name="sourcePath">源文件地址</param> /// <param name="targetPath">目标文件地址</param> /// <param name="bufferLength">缓冲区大小</param> /// <param name="suffix">加密后的文件后缀</param> /// <param name="volumeSize">分卷大小,0表示不分卷</param> /// <param name="coverExistedFile">是否覆盖已存在文件。若为False但存在文件,则会抛出异常</param> /// <param name="refreshFileProgress"></param> /// <returns></returns> public static FileInfo EncryptFile(this RijndaelManaged manager, string sourcePath, string targetPath, int bufferLength = 1024 * 1024, string suffix = null, int volumeSize = 0, bool coverExistedFile = false, RefreshFileProgress refreshFileProgress = null) { if (volumeSize < 0) { throw new ArgumentOutOfRangeException(nameof(volumeSize), "分卷大小不可小于0"); } if (string.IsNullOrEmpty(suffix) && volumeSize > 0) { throw new ArgumentException("加密文件扩展名为空和分卷加密不可同时存在"); } if (suffix == null) { suffix = ""; } string encryptedFileName = targetPath + suffix; CheckFileAndDirectoryExist(encryptedFileName, coverExistedFile); int fileCount = 0; try { using (FileStream streamSource = new FileStream(sourcePath, FileMode.Open, FileAccess.Read)) { FileStream streamTarget = new FileStream(encryptedFileName, FileMode.OpenOrCreate, FileAccess.Write); using (var encryptor = manager.CreateEncryptor()) { long currentSize = 0; int size; byte[] input = new byte[bufferLength]; byte[] output = new byte[bufferLength]; long fileLength = streamSource.Length; while ((size = streamSource.Read(input, 0, bufferLength)) != 0) { if (streamSource.Position == fileLength) { output = encryptor.TransformFinalBlock(input, 0, size); } else { encryptor.TransformBlock(input, 0, size, output, 0); } currentSize += size; if (volumeSize != 0 && currentSize > volumeSize) { streamTarget.Close(); streamTarget.Dispose(); currentSize = output.Length; fileCount++; encryptedFileName = targetPath + suffix + fileCount; CheckFileAndDirectoryExist(encryptedFileName, coverExistedFile); streamTarget = new FileStream(encryptedFileName, FileMode.OpenOrCreate, FileAccess.Write); } streamTarget.Write(output, 0, output.Length); streamTarget.Flush(); refreshFileProgress?.Invoke(sourcePath, encryptedFileName, fileLength, currentSize); //更新进度 } streamTarget.Close(); streamTarget.Dispose(); } } FileInfo encryptedFile = new FileInfo(targetPath + suffix); encryptedFile.Attributes = File.GetAttributes(sourcePath); return(encryptedFile); } catch (Exception ex) { HandleException(sourcePath, encryptedFileName, fileCount, ex, suffix); return(null); } }