/// <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> public void decryptFile(string srcFile, string destFile, string password) { using (FileStream fsrc = File.OpenRead(srcFile), fdest = File.OpenWrite(destFile)) { long lSize = (int)srcFile.Length; byte[] buffer = new byte[BUFSIZE]; int hasRead = -1; int totalRead = 0; byte[] IV = new byte[16]; byte[] SALT = new byte[16]; fsrc.Read(IV, 0, 16); fsrc.Read(SALT, 0, 16); PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, SALT, "SHA256", 100); byte[] KEY = pdb.GetBytes(16); //创建SM4解密器和SHA256散列器 SMFCBC smfdecryptor = new SMFCBC(); HashAlgorithm hasher = SHA256.Create(); using (CryptoStream cdest = new CryptoStream(fsrc, smfdecryptor.CreateDecryptor(KEY, IV), CryptoStreamMode.Read), chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) { BinaryReader brDest = new BinaryReader(cdest); lSize = brDest.ReadInt64(); ulong tag = brDest.ReadUInt64(); if (tag != SM4_TAG) { throw new Exception("文件非加密文件"); } long numReads = lSize / BUFSIZE; long numRest = (long)lSize % BUFSIZE; for (int i = 0; i < numReads; i++) { hasRead = brDest.Read(buffer, 0, buffer.Length); fdest.Write(buffer, 0, hasRead); chash.Write(buffer, 0, hasRead); totalRead += hasRead; } if (numRest > 0) { hasRead = brDest.Read(buffer, 0, (int)numRest); fdest.Write(buffer, 0, hasRead); chash.Write(buffer, 0, hasRead); totalRead += hasRead; } //关闭散列器 chash.Flush(); chash.Close(); fdest.Flush(); fdest.Close(); byte[] curHash = hasher.Hash; //和文件中的散列值比较 byte[] oldHash = new byte[hasher.HashSize / 8]; hasRead = brDest.Read(oldHash, 0, oldHash.Length); if ((oldHash.Length != hasRead) || (!CheckByteArrays(oldHash, curHash))) { throw new Exception("文件经过修改"); } brDest.Close(); if (totalRead != lSize) { throw new Exception("文件长度不对"); } } } }
/// <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; }
/// <summary> /// 可取消文件解密 /// </summary> /// <param name="srcFile"></param> /// <param name="destFile"></param> /// <param name="password"></param> /// <param name="asyOp"></param> private void decryptFileAsync(string srcFile, string destFile, string password, AsyncOperation asyOp) { FileStream fsrc = null, fdest = null; CryptoStream cdest = null, chash = null; BinaryReader brdest = null; try { fsrc = File.OpenRead(srcFile); fdest = File.OpenWrite(destFile); long lSize = (int)srcFile.Length; byte[] buffer = new byte[BUFSIZE]; int hasRead = -1; int totalRead = 0; byte[] IV = new byte[16]; byte[] SALT = new byte[16]; fsrc.Read(IV, 0, 16); fsrc.Read(SALT, 0, 16); PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, SALT, "SHA256", 100); byte[] KEY = pdb.GetBytes(16); //创建SM4解密器和SHA256散列器 SMFCBC smfdecryptor = new SMFCBC(); HashAlgorithm hasher = SHA256.Create(); cdest = new CryptoStream(fsrc, smfdecryptor.CreateDecryptor(KEY, IV), CryptoStreamMode.Read); chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write); BinaryReader brDest = new BinaryReader(cdest); lSize = brDest.ReadInt64(); ulong tag = brDest.ReadUInt64(); if (tag != SM4_TAG) { throw new Exception("文件解密出错(口令不对,或者不是加密文件)"); } long numReads = lSize / BUFSIZE; long numRest = (long)lSize % BUFSIZE; //增加报告 int totalNumber = (int)(lSize / BUFSIZE); for (int i = 0; i < numReads; i++) { hasRead = brDest.Read(buffer, 0, buffer.Length); fdest.Write(buffer, 0, hasRead); chash.Write(buffer, 0, hasRead); totalRead += hasRead; //报告进度 asyOp.Post(onTaskStateChangedReportDelgate, new TaskStateChangedEventArgs() { CryptState = CryptState.Decrypt, Description = "解密中", TaskID = 0, CurrentNumber = totalRead / BUFSIZE, TotalNumber = totalNumber }); //如果取消,则抛出取消异常 if (token.IsCancellationRequested) { throw new OperationCanceledException(token); } } if (numRest > 0) { hasRead = brDest.Read(buffer, 0, (int)numRest); fdest.Write(buffer, 0, hasRead); chash.Write(buffer, 0, hasRead); totalRead += hasRead; } //关闭散列器 chash.Flush(); chash.Close(); fdest.Flush(); fdest.Close(); byte[] curHash = hasher.Hash; //和文件中的散列值比较 byte[] oldHash = new byte[hasher.HashSize / 8]; hasRead = brDest.Read(oldHash, 0, oldHash.Length); if ((oldHash.Length != hasRead) || (!CheckByteArrays(oldHash, curHash))) { throw new Exception("文件经过修改"); } brDest.Close(); if (totalRead != lSize) { throw new Exception("文件长度不对"); } } catch (Exception e) { throw e; } finally { //顺序不可颠倒 if (brdest != null) { brdest.Close(); } if (chash != null) { chash.Close(); } if (cdest != null) { cdest.Close(); } if (fdest != null) { fdest.Close(); } if (fsrc != null) { fsrc.Close(); } } return; }
public void SMFCBCTest() { SMFCBC smfcbcAlg = SMFCBC.Create(); int total = 0; byte[] data = new byte[256]; for (int i = 0; i < 256; i++) { data[i] = (byte)i; } string FileName = "D:\\github\\SMFTool\\SMFcrypto\\CryptoTool\\CryptoToolTests\\bin\\Debug\\output.txt"; try { FileStream fStream = File.Open(FileName, FileMode.Create); SMFCBC smfcrypto = new SMFCBC(); CryptoStream cStream = new CryptoStream(fStream, smfcrypto.CreateEncryptor(smfcbcAlg.Key, smfcbcAlg.IV), CryptoStreamMode.Write); BinaryWriter sWriter = new BinaryWriter(cStream); try { sWriter.Write(data); sWriter.Write(data); total += data.Length; total += data.Length; } catch (Exception e) { Console.WriteLine("An error occurred: {0}", e.Message); } finally { sWriter.Close(); cStream.Close(); fStream.Close(); smfcrypto.Clear(); } } catch (CryptographicException e) { Console.WriteLine("A Cryptographic error occurred: {0}", e.Message); } catch (UnauthorizedAccessException e) { Console.WriteLine("A file error occurred: {0}", e.Message); } byte[] res; try { FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate); SMFCBC smfcrypto = new SMFCBC(); CryptoStream cStream = new CryptoStream(fStream, smfcrypto.CreateDecryptor(smfcbcAlg.Key, smfcbcAlg.IV), CryptoStreamMode.Read); BinaryReader sReader = new BinaryReader(cStream); byte[] resc = new byte[256]; try { for (int i = 0; i < 4; i++) { res = sReader.ReadBytes(256); Array.Copy(res, 0, resc, 0, res.Length); } } catch (Exception e) { Console.WriteLine("An error occurred: {0}", e.Message); } finally { sReader.Close(); cStream.Close(); fStream.Close(); smfcrypto.Clear(); } } catch (CryptographicException e) { Console.WriteLine("A Cryptographic error occurred: {0}", e.Message); } catch (UnauthorizedAccessException e) { Console.WriteLine("A file error occurred: {0}", e.Message); } smfcbcAlg.Clear(); return; }