C#文件加密和解密

下载

CSDN下载:https://download.csdn.net/download/myinc/9913318

Github:GitHub

如果没有积分,也可以关注我获取哟~【文件加密】
hi

// *

最近看了一下加密算法,对加密文件突然很感兴趣,就研究了一下:

  1. 加密算法和加密后的长度问题(这里用的AES);
  2. 加密大文件使用流的方式一点一点加密(防止一次性吃掉很多内存);
  3. 加密过程的回调;
  4. 文件结构;

截图

加密:
加密

解密:
解密

选择文件:
选择文件

内存及CPU的使用:
内存及CPU的使用

一、算法

首先,文件要加密就一定要解密,所以一定要找个能解密的算法,这个不用多说……其实加密解密算法也算是C#里自带了,代码如下:

/// <summary>
/// 加密
/// </summary>
/// <param name="array">要加密的 byte[] 数组</param>
/// <param name="key"></param>
/// <returns></returns>
public static byte[] Encrypt(byte[] array, string key)
{key = FmtPassword(key);byte[] keyArray = Encoding.UTF8.GetBytes(key);RijndaelManaged rDel = new RijndaelManaged();rDel.Key = keyArray;rDel.Mode = CipherMode.ECB;rDel.Padding = PaddingMode.PKCS7;ICryptoTransform cTransform = rDel.CreateEncryptor();byte[] resultArray = cTransform.TransformFinalBlock(array, 0, array.Length);return resultArray;
} /// <summary>
/// 解密
/// </summary>
/// <param name="array">要解密的 byte[] 数组</param>
/// <param name="key"></param>
/// <returns></returns>
public static byte[] Decrypt(byte[] array, string key)
{key = FmtPassword(key);byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);RijndaelManaged rDel = new RijndaelManaged();rDel.Key = keyArray;rDel.Mode = CipherMode.ECB;rDel.Padding = PaddingMode.PKCS7;ICryptoTransform cTransform = rDel.CreateDecryptor();byte[] resultArray = cTransform.TransformFinalBlock(array, 0, array.Length);return resultArray;
}

这里要注意一点,AES加密的话,密码是需要32位的,不然会提示错误:DES和AES加密:指定键的大小对于此算法无效
所以需要自己把不够长度的密码填充一下(超出长度的也需要处理一下),避免出现这种错误

二、流

文件加密的功能网上有很多,我发现有很多直接把文件全部读取出来,然后加密整个文件。这种方法在处理大文件会消耗非常大的内存,所以需要注意不能一次性把文件全加密。

注1: 关于加密的部分,可以只加密文件的一部分数据,这样可以保证加密速度。

注2: 使用流读取部分,循环加密的时候,AES加密后的内容长度会增加,比如要加密一个 byte[1024] 大小的内容,加密后会变成 byte[1024+16] ,这一点可以自己试一试。

三、进度

进度方面是很有必要的,在加密大文件的时候,如果光等着没有进度也显得很尴尬,所以做一个委托,来把进度回调出来。

// 定义
public delegate void ProgressHandler(object sender, ProgressEventArgs e);// 使用
progress?.Invoke(sender, new ProgressEventArgs(fsRead.Position, fsRead.Length));

四、文件结构

加密文件后的文件结构是要自己重新做定义的,使自己的程序能读懂,并且能成功解密即可。这里贴一个文件加密的方法:
里面有很多我自己写的方法,下面会给链接地址

/// <summary>
/// 文件加密
/// </summary>
/// <param name="srcFile">源文件</param>
/// <param name="dstFile">目标文件</param>
/// <param name="password">加密密码</param>
/// <param name="progress">回调进度</param>
/// <param name="overwrite">是否覆盖已有目标文件</param>
/// <returns>
/// >0:操作成功(操作共计秒数)
/// -11:要加密的文件不存在
/// -12:加密后的目标文件已存在
/// -404:未知错误,操作失败
/// </returns>
public static int Encrypt(string srcFile, string dstFile, string password, ProgressDelegate.ProgressHandler progress = null, object sender = null, bool overwrite = true)
{DateTime beginTime = DateTime.Now;if (!File.Exists(srcFile)) return -11; //要加密的文件不存在if (File.Exists(dstFile) && !overwrite) return -12;//加密后的目标文件已存在string fmtPwd = AesTool.FmtPassword(password);string pwdMd5 = MD5Tool.Encrypt(MD5Tool.Encrypt(fmtPwd));string md5 = FileTool.GetMD5(srcFile);using (FileStream fsRead = new FileStream(srcFile, FileMode.Open)){using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create)){try{//写入文件类型标识和版本号byte[] filetypeandversion = Encoding.Default.GetBytes(FileType + FileVersion);fsWrite.Write(filetypeandversion, 0, filetypeandversion.Length);//文件头部数据定义List<byte[]> headdata = new List<byte[]>(){Encoding.Default.GetBytes(FileType),Encoding.Default.GetBytes(md5),Encoding.Default.GetBytes(AesTool.Encrypt(fmtPwd,AesTool.DefaultPassword)),Encoding.Default.GetBytes(pwdMd5),Encoding.Default.GetBytes(DateTime.Now.ToString())};//写入头部信息个数byte[] count = BitConverter.GetBytes(headdata.Count);fsWrite.Write(count, 0, count.Length);//写入各部分长度for (int i = 0; i < headdata.Count; i++){byte[] length = BitConverter.GetBytes(headdata[i].Length);fsWrite.Write(length, 0, length.Length);}//写入各部分数据for (int i = 0; i < headdata.Count; i++){fsWrite.Write(headdata[i], 0, headdata[i].Length);}//写入文件源数据int readCount = 0;byte[] buffer = new byte[FileBuffer];while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0){if (readCount != buffer.Length){byte[] temp = new byte[readCount];Buffer.BlockCopy(buffer, 0, temp, 0, readCount);byte[] enbyte = AesTool.Encrypt(temp, fmtPwd);fsWrite.Write(enbyte, 0, enbyte.Length);}else{byte[] enbyte = AesTool.Encrypt(buffer, fmtPwd);fsWrite.Write(enbyte, 0, enbyte.Length);}progress?.Invoke(sender, new ProgressEventArgs(fsRead.Position, fsRead.Length));}return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功}catch (Exception e) { }}//加密失败后,删除加密的文件try { File.Delete(dstFile); } catch (Exception e) { }}return -404;//未知错误,操作失败
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的!

大家好&#xff0c;我是磊哥。今天我们来聊一聊在基于SpringBoot前后端分离开发模式下&#xff0c;如何友好的返回统一的标准格式以及如何优雅的处理全局异常。首先我们来看看为什么要返回统一的标准格式&#xff1f;为什么要对SpringBoot返回统一的标准格式在默认情况下&#…

zabbix企业应用之监控docker容器资源情况

关于docker的监控&#xff0c;无论开源的CAdvisor、Data Dog还是我自己写的监控&#xff08;http://dl528888.blog.51cto.com/2382721/1635951&#xff09;&#xff0c;不是通过docker的stats api就是使用socket来进行。单独看一个主机的监控项还行&#xff0c;比如只查看容器t…

使用了synchronized,竟然还有线程安全问题!

线程安全问题一直是系统亘古不变的痛点。这不&#xff0c;最近在项目中发了一个错误使用线程同步的案例。表面上看已经使用了同步机制&#xff0c;一切岁月静好&#xff0c;但实际上线程同步却毫无作用。关于线程安全的问题&#xff0c;基本上就是在挖坑与填坑之间博弈&#xf…

序列图| 软件工程

什么是时序图&#xff1f; (What is Sequence Diagram?) Sequence Diagram is a "Connection Diagram" that represents a single structure or storyline executing in a system. It is the second most used UML diagram behind the class diagram. Sequence Diag…

终极解密输入网址按回车到底发生了什么?

详解输入网址点击回车&#xff0c;后台到底发生了什么。透析 HTTP 协议与 TCP 连接之间的千丝万缕的关系。掌握为何是三次握手四次挥手&#xff1f;time_wait 存在的意义是什么&#xff1f;全面图解重点问题&#xff0c;再也不用担心面试问这个问题。大致流程URL 解析&#xff…

unity, 相机空间 与 相机gameObject的局部空间

在unity里 相机空间 与 相机gameObject的局部空间 不重合。 Camera.worldToCameraMatrix的文档中有这样一句话&#xff1a; Note that camera space matches OpenGL convention: cameras forward is the negative Z axis. This is different from Unitys convention, where for…

Winform实现漂亮动画-小火车

一、起因 最近在做一个Winform的项目&#xff0c;其中需要一些加载动画&#xff0c;所以就搜索了一下找些思路&#xff0c;以下链接是本文的参考。 参考&#xff1a;Jeremie Martinez &#xff08;译文链接&#xff09; 注&#xff1a;原文中并没有给出图片资源&#xff0c;图…

synchronized 加锁 this 和 class 的区别!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;synchronized 是 Java 语言中处理并发问题的一种常用手段&#xff0c;它也被我们亲切的称之为“Java 内置锁”&#xff0c;由…

C# WinForm窗体四周阴影效果

一、起因 关于winform窗体无边框的问题很简单&#xff0c;只需要设置winform的窗体属性即可&#xff1a; FormBorderStyle FormBorderStyle.None; 但是这中无边框窗口实现的效果和背景完全没有层次的感觉&#xff0c;所以能加上阴影&#xff0c;突出窗口显示的感觉。 二、…

synchronized 优化手段之锁膨胀机制!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;synchronized 在 JDK 1.5 之前性能是比较低的&#xff0c;在那时我们通常会选择使用 Lock 来替代 synchronized。然而这个情…

NTFS USN的Create和工具代码汇总

1、 因为之前把相关代码放在了GitHub上&#xff0c;后来突然有人帮忙改了些个BUG&#xff0c;非常感谢 760193107&#xff0c;所以就写了个完整点的例子&#xff0c;希望对别人有所帮助。 GitHub项目地址 2、错误码&#xff1a;ERROR_JOURNAL_NOT_ACTIVE 在测试时&#xff…

在Java中,负数的绝对值不一定是正数!

作者 l Hollis来源 l Hollis&#xff08;ID&#xff1a;hollischuang&#xff09;绝对值是指一个数在数轴上所对应点到原点的距离&#xff0c;所以&#xff0c;在数学领域&#xff0c;正数的绝对值是这个数本身&#xff0c;负数的绝对值应该是他的相反数。这几乎是每个人都知道…

自己写着玩(二)

转载于:https://www.cnblogs.com/wangmengmeng/p/4572611.html

实战:隐藏SpringBoot中的私密数据!

这几天公司在排查内部数据账号泄漏&#xff0c;原因是发现某些实习生小可爱居然连带着账号、密码将源码私传到GitHub上&#xff0c;导致核心数据外漏&#xff0c;孩子还是没挨过社会毒打&#xff0c;这种事的后果可大可小。说起这个我是比较有感触的&#xff0c;之前我TM被删库…

JS的条形码和二维码生成

一、前言 最近做项目用到了JS生成条形码和二维码&#xff0c;内容不多&#xff0c;整理一下方便使用。 2018年7月5日更新&#xff1a; 二维码生成时&#xff0c;如果长度太长会有异常&#xff1a; Uncaught Error: code length overflow. (1604>1056) 创建的时候&#…

synchronized 中的 4 个优化,你知道几个?

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;synchronized 在 JDK 1.5 时性能是比较低的&#xff0c;然而在后续的版本中经过各种优化迭代&#xff0c;它的性能也得到了前…

31Exchange Server 2010跨站点部署-搬迁Exchange服务器到分支机构

16.4 将EX07和EX08搬迁到上海分支机构首先我在上海分支机机构站点下创建一个CAS阵列&#xff0c;命令如下&#xff1a;下面获取下当前域中的CAS阵列信息16.4.1搬迁CAS,HT服务器1、从广州总部NLB群集删除EX07主机2、修改EX07的IP地址为分支机构IP地址 192.168.20.27(上海分支机构…

@Autowired的这些骚操作,你都知道吗?

前言最近review别人代码的时候&#xff0c;看到了一些Autowired不一样的用法&#xff0c;觉得有些意思&#xff0c;特定花时间研究了一下&#xff0c;收获了不少东西&#xff0c;现在分享给大家。也许Autowired比你想象中更强大。1. Autowired的默认装配我们都知道在spring中Au…

C# Winform 使用二维码

关于C# Winform 程序中使用二维码的使用记录&#xff1a; 1、使用 Nuget 安装 ZXing.Net 程序包&#xff1b; 2、调用代码&#xff1a; private void button1_Click(object sender, EventArgs e) {BarcodeWriter writer new BarcodeWriter();writer.Format BarcodeFormat…

[Swust OJ 85]--单向公路(BFS)

题目链接:http://acm.swust.edu.cn/problem/0085/ Time limit(ms): 5000      Memory limit(kb): 65535Description某个地区有许多城镇&#xff0c;但并不是每个城镇都跟其他城镇有公路连接&#xff0c;且有公路的并不都能双向行驶。现在我们把这些城镇间的公路分布及允许…