C#的DES文件加解密工具类

发布时间:2020-04-07 23:20:59 作者:tjxyrjxl
来源:网络 阅读:889

using System;

using System.Collections.Generic;

using System.Text;

using System.Security.Cryptography;

using System.IO;

namespace www.xinduofen.com

{

    class FileDES

    {

        ///

        /// 加密文件随机数生成

        ///

        private static RandomNumberGenerator rand = new RNGCryptoServiceProvider();

        private const ulong FC_TAG = 0xFC010203040506CF;

        private const int BUFFER_SIZE = 32 * 1024;

        ///

        /// 异常内部处理类

        ///

        private class CryptoHelpException : ApplicationException

        {

            public CryptoHelpException(string msg) : base(msg) { }

        }

        ///

        /// 加密文件,此方法不对异常进行处理,需要调用方进行捕获

        ///

        /// 待加密文件

        /// 加密后输出文件

        /// 加密密码

        /// 方法未产生任何异常 - 成功

        public static void EncryptFile(string inFile, string outFile, string password)

        {

            using (FileStream fin = File.OpenRead(inFile),

                fout = File.OpenWrite(outFile))

            {

                // 获取IV和salt

                byte[] IV = GenerateRandomBytes(16);

                byte[] salt = GenerateRandomBytes(16);

                // 创建加密对象

                SymmetricAlgorithm sma = FileDES.CreateRijndael(password, salt);

                sma.IV = IV;

                // 在输出文件开始部分写入IV和salt

                fout.Write(IV, 0, IV.Length);

                fout.Write(salt, 0, salt.Length);

                // 创建散列加密

                HashAlgorithm hasher = SHA256.Create();

                long lSize = fin.Length; // 输入文件长度

                byte[] bytes = new byte[BUFFER_SIZE]; // 缓存

                int read = -1; // 输入文件读取数量

                int value = 0;

                using (CryptoStream cout = new CryptoStream(fout, sma.CreateEncryptor(), CryptoStreamMode.Write),

                    chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))

                {

                    BinaryWriter bw = new BinaryWriter(cout);

                    bw.Write(lSize);

                    bw.Write(FC_TAG);

                    // 读写字节块到加密流缓冲区

                    while ((read = fin.Read(bytes, 0, bytes.Length)) != 0)

                    {

                        cout.Write(bytes, 0, read);

                        chash.Write(bytes, 0, read);

                        value += read;

                    }

                    // 关闭加密流

                    chash.Flush();

                    chash.Close();

                    // 读取散列

                    byte[] hash = hasher.Hash;

                    // 输入文件写入散列

                    cout.Write(hash, 0, hash.Length);

                    // 关闭文件流

                    cout.Flush();

                    cout.Close();

                }

            }

        }

        ///

        /// 解密文件,此方法不对异常进行处理,需要调用方进行捕获

        ///

        /// 待解密文件

        /// 解密后输出文件

        /// 解密密码

        /// 方法未产生任何异常 - 成功

        public static void DecryptFile(string inFile, string outFile, string password)

        {

            // 创建打开文件流

            using (FileStream fin = File.OpenRead(inFile),

                fout = File.OpenWrite(outFile))

            {

                int size = (int)fin.Length;

                byte[] bytes = new byte[BUFFER_SIZE];

                int read = -1;

                int value = 0;

                int outValue = 0;

                byte[] IV = new byte[16];

                fin.Read(IV, 0, 16);

                byte[] salt = new byte[16];

                fin.Read(salt, 0, 16);

                SymmetricAlgorithm sma = FileDES.CreateRijndael(password, salt);

                sma.IV = IV;

                value = 32;

                long lSize = -1;

                // 创建散列对象, 校验文件

                HashAlgorithm hasher = SHA256.Create();

                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();

                    byte[] curHash = hasher.Hash;

                    // 获取比较和旧的散列对象

                    byte[] oldHash = new byte[hasher.HashSize / 8];

                    read = cin.Read(oldHash, 0, oldHash.Length);

                    if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash)))

                        throw new CryptoHelpException("文件被破坏");

                }

                if (outValue != lSize)

                    throw new CryptoHelpException("文件大小不匹配");

            }

        }

        ///

        /// 创建加密对象

        ///

        /// 密码

        /// 密钥salt

        /// 加密对象

        private static SymmetricAlgorithm CreateRijndael(string password, byte[] salt)

        {

            PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt, "SHA256", 1000);

            SymmetricAlgorithm sma = Rijndael.Create();

            sma.KeySize = 256;

            sma.Key = pdb.GetBytes(32);

            sma.Padding = PaddingMode.PKCS7;

            return sma;

        }

        ///

        /// 检验两个Byte数组是否相同

        ///

        /// Byte数组

        /// Byte数组

        /// true-相等

        private static bool CheckByteArrays(byte[] b1, byte[] b2)

        {

            if (b1.Length == b2.Length)

            {

                for (int i = 0; i < b1.Length; ++i)

                {

                    if (b1[i] != b2[i])

                        return false;

                }

                return true;

            }

            return false;

        }

        ///

        /// 生成指定长度的随机Byte数组

        ///

        /// Byte数组长度

        /// 随机Byte数组

        private static byte[] GenerateRandomBytes(int count)

        {

            byte[] bytes = new byte[count];

            rand.GetBytes(bytes);

            return bytes;

        }

    }

}

文章出自:越康体育

推荐阅读:
  1. 如何用DES算法实现加解密?
  2. 如何实现PHP的DES加解密方法代码

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

文件 des

上一篇:内链和外链到底是什么?

下一篇:面试问题——Activity的生命周期

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》