一般文件的加密与解密

使用对称加密

可以使用对称加密算法类DESCryptoServiceProvider的CreateDecryptor()方法和CryptoStream类实现对文件的加密和解密。

注意

(1)对称加密算法以块为单位加密数据,一次加密一个数据块,所以也称为块密码。这些算法通过加密将n字节的输入块转换为加密字节的输出块。由于n很小,因此当要加密的数据值大于n时,则必须逐块加密,且一次加密一个块。如果数据值小于n,必须将其扩展为n字节后才能进行处理。.NET类库提供的加密算法类本身会自动解决以上问题,因此编程时不需要考虑这些问题。
(2).NET类库中提供的块密码类使用密码块链(Cipher Block Chaining,CBC)的默认链模式,但可以根据需要更改此默认设置。该模式下,通过使用一个密钥Key和一个初始化向量(Initialization Vector,IV)对数据执行加密转换。通信双方都必须知道这个Key和IV才能加密和解密数据。

例子:使用对称算法实现加密和解密文件

页面如下所示:
在这里插入图片描述
以下代码可以运行(主界面)

using System.Windows.Forms;
using System.IO;
using System.Security.Cryptography;

namespace DiffieHellman
{
    public partial class Form2 : Form
    {
        private AutoSizeWinformclass asc = new AutoSizeWinformclass();

        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_SizeChanged(object sender, EventArgs e)
        {
            if (asc != null)
            {
                asc.controlAutoSize(this);
            }
        }

        private void btn_Encrypt_Click(object sender, EventArgs e)
        {
            //获取源文件路径
            string strFile = tbx_File.Text;
            //获取加密密钥
            string strKey = tbx_Key.Text;
            //获取加密后的文件路径
            string strEnFile  = tbx_EncryptFile.Text;
            //设置向量
            byte[] myIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xDF };
            //设置密钥
            byte[] myKey = System.Text.Encoding.UTF8.GetBytes(strKey);
            if (myKey.Length < 8)
            {
                // 如果密钥长度不足 8 字节,进行填充
                myKey = myKey.Concat(new byte[8 - myKey.Length]).ToArray();
            }

            //源文件的文件流
            FileStream myInStream = new FileStream(strFile, FileMode.Open, FileAccess.Read);
            //加密后文件的文件流
            FileStream myOutStream = new FileStream(strEnFile, FileMode.OpenOrCreate, FileAccess.Write);
            //初始文件流的长度
            myOutStream.SetLength(0);
            //定义缓冲区
            byte[] myBytes = new byte[100];
            //定义不断变化的流的长度
            long myInLength = 0;
            //获取源文件的文件流的长度
            long myLength = myInStream.Length;
            //定义标准的加密算法对象
            DESCryptoServiceProvider myProvider = new DESCryptoServiceProvider();
            if (myKey.Length != 8)
            {
                throw new ArgumentException("The key must be exactly 8 bytes long for DES.");
            }

            //实现将数据流链接到加密转换的流
            CryptoStream myCryptoStream = new CryptoStream(myOutStream,myProvider.CreateEncryptor(myKey,myIV), CryptoStreamMode.Write);
            //从源文件中一次读取100个字节
            while( myInLength < myLength )
            {
                //读取源文件流
                int mylen = myInStream.Read(myBytes, 0, 100);
                //写入加密转换的流
                myCryptoStream.Write(myBytes, 0, mylen);
                //计算写入的流长度
                myInLength += mylen;
            }
            //关闭资源
            myCryptoStream.Close();
            myInStream.Close();
            myOutStream.Close();
            MessageBox.Show("文件加密完成");

        }

        private void btn_Decrypt_Click(object sender, EventArgs e)
        {
            //获取源文件路径
            string strFile = tbx_EncryptFile.Text;
            //获取解密密钥
            string strKey = tbx_Key.Text;
            //获取解密后的文件路径
            string strEnFile = tbx_DecryptFile.Text;
            //设置向量
            byte[] myIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            //设置密钥
            byte[] myKey = System.Text.Encoding.UTF8.GetBytes(strKey);
            if (myKey.Length < 8)
            {
                // 如果密钥长度不足 8 字节,进行填充
                myKey = myKey.Concat(new byte[8 - myKey.Length]).ToArray();
            }
            //源文件的文件流
            FileStream myInStream = new FileStream(strFile,FileMode.Open,FileAccess.Read);
            //解密后的文件的文件流
            FileStream myOutStream = new FileStream(strEnFile, FileMode.OpenOrCreate, FileAccess.Write);
            //初始化文件流的长度
            myOutStream.SetLength(0);
            //定义缓冲区
            byte[] myBytes = new byte[100];
            //获取源文件流的长度
            long myLength = myInStream.Length;
            //定义不断变化的流的长度
            long myInLength = 0;
            //定义标准的加密算法实例
            DESCryptoServiceProvider myProvide = new DESCryptoServiceProvider();
            //实现将数据流链接到解密转换的流
            CryptoStream myDetoStream = new CryptoStream(myOutStream, myProvide.CreateDecryptor(myKey, myIV), CryptoStreamMode.Write);
            //从源文件流中每次读取100字节,然后写入解密转换的流
            while(myInLength < myLength)
            {
                //读取源文件流
                int mylen = myInStream.Read(myBytes, 0, 100);
                if (mylen == 0) break;  // 防止在文件末尾时读取0字节  
                //写入解密转换的流
                myDetoStream.Write(myBytes, 0, mylen);
                //计算写入的长度
                myInLength += mylen;
            }
            myDetoStream.Flush();
            myDetoStream.Close();
            myInStream.Close();
            myOutStream.Close();
            MessageBox.Show("文件解密成功");
        }
    }
}

这里加入了控件跟随窗体自动变化的代码AutoSizeWinformclass类

using System.Windows.Forms;
using System.IO;
using System.Security.Cryptography;

namespace DiffieHellman
{
    public partial class Form2 : Form
    {
        private AutoSizeWinformclass asc = new AutoSizeWinformclass();

        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_SizeChanged(object sender, EventArgs e)
        {
            if (asc != null)
            {
                asc.controlAutoSize(this);
            }
        }

        private void btn_Encrypt_Click(object sender, EventArgs e)
        {
            //获取源文件路径
            string strFile = tbx_File.Text;
            //获取加密密钥
            string strKey = tbx_Key.Text;
            //获取加密后的文件路径
            string strEnFile  = tbx_EncryptFile.Text;
            //设置向量
            byte[] myIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xDF };
            //设置密钥
            byte[] myKey = System.Text.Encoding.UTF8.GetBytes(strKey);
            if (myKey.Length < 8)
            {
                // 如果密钥长度不足 8 字节,进行填充
                myKey = myKey.Concat(new byte[8 - myKey.Length]).ToArray();
            }

            //源文件的文件流
            FileStream myInStream = new FileStream(strFile, FileMode.Open, FileAccess.Read);
            //加密后文件的文件流
            FileStream myOutStream = new FileStream(strEnFile, FileMode.OpenOrCreate, FileAccess.Write);
            //初始文件流的长度
            myOutStream.SetLength(0);
            //定义缓冲区
            byte[] myBytes = new byte[100];
            //定义不断变化的流的长度
            long myInLength = 0;
            //获取源文件的文件流的长度
            long myLength = myInStream.Length;
            //定义标准的加密算法对象
            DESCryptoServiceProvider myProvider = new DESCryptoServiceProvider();
            if (myKey.Length != 8)
            {
                throw new ArgumentException("The key must be exactly 8 bytes long for DES.");
            }

            //实现将数据流链接到加密转换的流
            CryptoStream myCryptoStream = new CryptoStream(myOutStream,myProvider.CreateEncryptor(myKey,myIV), CryptoStreamMode.Write);
            //从源文件中一次读取100个字节
            while( myInLength < myLength )
            {
                //读取源文件流
                int mylen = myInStream.Read(myBytes, 0, 100);
                //写入加密转换的流
                myCryptoStream.Write(myBytes, 0, mylen);
                //计算写入的流长度
                myInLength += mylen;
            }
            //关闭资源
            myCryptoStream.Close();
            myInStream.Close();
            myOutStream.Close();
            MessageBox.Show("文件加密完成");

        }

        private void btn_Decrypt_Click(object sender, EventArgs e)
        {
            //获取源文件路径
            string strFile = tbx_EncryptFile.Text;
            //获取解密密钥
            string strKey = tbx_Key.Text;
            //获取解密后的文件路径
            string strEnFile = tbx_DecryptFile.Text;
            //设置向量
            byte[] myIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            //设置密钥
            byte[] myKey = System.Text.Encoding.UTF8.GetBytes(strKey);
            if (myKey.Length < 8)
            {
                // 如果密钥长度不足 8 字节,进行填充
                myKey = myKey.Concat(new byte[8 - myKey.Length]).ToArray();
            }
            //源文件的文件流
            FileStream myInStream = new FileStream(strFile,FileMode.Open,FileAccess.Read);
            //解密后的文件的文件流
            FileStream myOutStream = new FileStream(strEnFile, FileMode.OpenOrCreate, FileAccess.Write);
            //初始化文件流的长度
            myOutStream.SetLength(0);
            //定义缓冲区
            byte[] myBytes = new byte[100];
            //获取源文件流的长度
            long myLength = myInStream.Length;
            //定义不断变化的流的长度
            long myInLength = 0;
            //定义标准的加密算法实例
            DESCryptoServiceProvider myProvide = new DESCryptoServiceProvider();
            //实现将数据流链接到解密转换的流
            CryptoStream myDetoStream = new CryptoStream(myOutStream, myProvide.CreateDecryptor(myKey, myIV), CryptoStreamMode.Write);
            //从源文件流中每次读取100字节,然后写入解密转换的流
            while(myInLength < myLength)
            {
                //读取源文件流
                int mylen = myInStream.Read(myBytes, 0, 100);
                if (mylen == 0) break;  // 防止在文件末尾时读取0字节  
                //写入解密转换的流
                myDetoStream.Write(myBytes, 0, mylen);
                //计算写入的长度
                myInLength += mylen;
            }
            myDetoStream.Flush();
            myDetoStream.Close();
            myInStream.Close();
            myOutStream.Close();
            MessageBox.Show("文件解密成功");
        }
    }
}

不需要的可以直接将主界面中的下面代码注释即可。

 private AutoSizeWinformclass asc = new AutoSizeWinformclass();
  private void Form2_SizeChanged(object sender, EventArgs e)
        {
            if (asc != null)
            {
                asc.controlAutoSize(this);
            }
        }

运行效果如下所示

运行时要提前写好所有的文件路径,加密密钥一定要保证是8位。文件路径要提前创建好,其他的可以不创建,运行时没有会字节创建文件。
在这里插入图片描述

有问题可以直接在评论区讨论

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值