/// <summary> /// 加密文件 /// </summary> /// <param name="srcFile">源绝对路径</param> /// <param name="destFile">目的绝对路径</param> public void encryptFile(string srcFile, string destFile, string password) { using (FileStream fsrc = File.OpenRead(srcFile), fdest = File.OpenWrite(destFile)) { long lSize = fsrc.Length; byte[] buffer = new byte[BUFSIZE]; int tmpRead = -1; int totalRead = 0; byte[] IV = SMFCBC.GenerateRandomBytes(16); byte[] SALT = SMFCBC.GenerateRandomBytes(16); PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, SALT, "SHA256", 100); byte[] KEY = pdb.GetBytes(16); //往文件头添加IV和SALT值 fdest.Write(IV, 0, IV.Length); fdest.Write(SALT, 0, SALT.Length); //创建SM4加密器和SHA256散列器 SMFCBC smfencryptor = new SMFCBC(); HashAlgorithm hasher = SHA256.Create(); using (CryptoStream cdest = new CryptoStream(fdest, smfencryptor.CreateEncryptor(KEY, IV), CryptoStreamMode.Write), chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) { //包装加密流 BinaryWriter bw_dest = new BinaryWriter(cdest); //加密开头为长度和文件标识 bw_dest.Write(lSize); bw_dest.Write(SM4_TAG); while ((tmpRead = fsrc.Read(buffer, 0, buffer.Length)) != 0) { bw_dest.Write(buffer, 0, tmpRead); chash.Write(buffer, 0, tmpRead); totalRead += tmpRead; } //关闭SHA256散列器 chash.Flush(); chash.Close(); byte[] HASH = hasher.Hash; bw_dest.Write(HASH, 0, HASH.Length); //关闭二进制包装类 bw_dest.Flush(); bw_dest.Close(); } } }
/// <summary> /// 可取消文件加密 /// </summary> /// <param name="srcFile"></param> /// <param name="destFile"></param> /// <param name="password"></param> /// <param name="asyOp"></param> private void encryptFileAsync(string srcFile, string destFile, string password, AsyncOperation asyOp) { FileStream fsrc = null, fdest = null; CryptoStream cdest = null, chash = null; BinaryWriter bwdest = null; try { fsrc = File.OpenRead(srcFile); fdest = File.OpenWrite(destFile); long lSize = fsrc.Length; byte[] buffer = new byte[BUFSIZE]; int tmpRead = -1; int totalRead = 0; byte[] IV = SMFCBC.GenerateRandomBytes(16); byte[] SALT = SMFCBC.GenerateRandomBytes(16); PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, SALT, "SHA256", 100); byte[] KEY = pdb.GetBytes(16); //往文件头添加IV和SALT值 fdest.Write(IV, 0, IV.Length); fdest.Write(SALT, 0, SALT.Length); //创建SM4加密器和SHA256散列器 SMFCBC smfencryptor = new SMFCBC(); HashAlgorithm hasher = SHA256.Create(); cdest = new CryptoStream(fdest, smfencryptor.CreateEncryptor(KEY, IV), CryptoStreamMode.Write); chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write); //包装加密流 bwdest = new BinaryWriter(cdest); //加密开头为长度和文件标识 bwdest.Write(lSize); bwdest.Write(SM4_TAG); //增加报告进度 int totalNumber = (int)(lSize / BUFSIZE); while ((tmpRead = fsrc.Read(buffer, 0, buffer.Length)) != 0) { bwdest.Write(buffer, 0, tmpRead); chash.Write(buffer, 0, tmpRead); totalRead += tmpRead; //报告进度 asyOp.Post(onTaskStateChangedReportDelgate, new TaskStateChangedEventArgs() { CryptState = CryptState.Encrypt, Description = "加密中", TaskID = 0, CurrentNumber = totalRead / BUFSIZE, TotalNumber = totalNumber }); //如果取消,则抛出取消异常 if (token.IsCancellationRequested) { throw new OperationCanceledException(token); } } //关闭SHA256散列器 chash.Flush(); chash.Close(); byte[] HASH = hasher.Hash; bwdest.Write(HASH, 0, HASH.Length); //关闭二进制包装类 bwdest.Flush(); bwdest.Close(); } catch (Exception e) { throw e; } finally { //顺序不可颠倒 if (bwdest != null) { bwdest.Close(); } if (chash != null) { chash.Close(); } if (cdest != null) { cdest.Close(); } if (fdest != null) { fdest.Close(); } if (fsrc != null) { fsrc.Close(); } } return; }