/// <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; }
/// <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("文件长度不对"); } } } }
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; }