Exemplo n.º 1
0
        /// <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;
        }
Exemplo n.º 2
0
        /// <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("文件长度不对");
                    }
                }
            }
        }
Exemplo n.º 3
0
        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;
        }