C# 实现文件加解密(2):解密文件

该代码段展示了一个使用C#编写的文件解密方法,它首先校验文件完整性,然后读取并解密文件内容,最后对比散列值确保解密后的文件未被篡改。过程中涉及了Rijndael加密算法、SHA256散列校验以及CryptoStream类的应用。
        /// <summary>
        /// 解密文件
        /// </summary>
        /// <param name="inFile">待解密文件</param>
        /// <param name="outFile">解密后输出文件</param>
        /// <param name="password">解密密码</param>
        public static void DecryptFile(string inFile, string outPath, string password)
        {
            try
            {
                int outValue = 0;
                long lSize = -1;
                byte[] oldHash = null;
                byte[] curHash = null;
                int read = -1;
                // 创建打开文件流
                using (FileStream fin = File.OpenRead(inFile))
                {
                    int size = (int)fin.Length;
                    byte[] bytes = new byte[BUFFER_SIZE];
                    int value = 0;
                    int len = fin.ReadByte();
                    byte[] tem1 = new byte[len];
                    fin.Read(tem1, 0, tem1.Length);
                    int len2 = System.BitConverter.ToInt32(tem1, 0);
                    byte[] tem2 = new byte[len2];
                    fin.Read(tem2, 0, tem2.Length);
                    String filename = Encoding.UTF8.GetString(tem2);
                    String outFile = Path.Combine(outPath, filename);
                    byte[] IV = new byte[16];
                    fin.Read(IV, 0, 16);
                    byte[] salt = new byte[16];
                    fin.Read(salt, 0, 16);
                    SymmetricAlgorithm sma = Common.CreateRijndael(password, salt);
                    sma.IV = IV;
                    value = 32;
                    // 创建散列对象, 校验文件
                    HashAlgorithm hasher = SHA256.Create();
                    using (FileStream fout = File.OpenWrite(outFile))
                    {
                        using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read),
                            chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
                        {
                            // 读取文件长度
                            BinaryReader br = new BinaryReader(cin);
                            lSize = br.ReadInt64();
                            ulong tag = br.ReadUInt64();
                            if (FC_TAG != tag)
                                throw new CryptoHelpException("文件被破坏");
                            long numReads = lSize / BUFFER_SIZE;
                            long slack = (long)lSize % BUFFER_SIZE;
                            for (int i = 0; i < numReads; ++i)
                            {
                                read = cin.Read(bytes, 0, bytes.Length);
                                fout.Write(bytes, 0, read);
                                chash.Write(bytes, 0, read);
                                value += read;
                                outValue += read;
                            }
                            if (slack > 0)
                            {
                                read = cin.Read(bytes, 0, (int)slack);
                                fout.Write(bytes, 0, read);
                                chash.Write(bytes, 0, read);
                                value += read;
                                outValue += read;
                            }
                            chash.Flush();
                            chash.Close();
                            fout.Flush();
                            fout.Close();
                            curHash = hasher.Hash;
                            // 获取比较和旧的散列对象
                            oldHash = new byte[hasher.HashSize / 8];
                            read = cin.Read(oldHash, 0, oldHash.Length);
                        }
                    }
                }
                if (outValue != lSize)
                {
                    throw new CryptoHelpException("文件大小不匹配");
                }
                if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash)))
                {
                    throw new CryptoHelpException("文件被破坏");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message); 
            }
        }

这段代码主要做了3个事情
1.首先是校验文件

2.是获取原始文件名称

3.解密文件成原始文件

提供完成的C#实现为文件加解密工具:

EnFile: 文件加密的软件,硬加密

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

影像熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值