.NET下对二进制文件进行加密解密(C#)
下面的类实现了文件的加密和解密操作,试验了几种文件类型均没有问题,现在和大家共享一下。namespace mycryptohelp
{
/// <summary>
/// 异常处理类
/// </summary>
public class cryptohelpexception : applicationexception
{
public cryptohelpexception(string msg):base(msg){}
}
/// <summary>
/// crypthelp
/// </summary>
public class cryptohelp
{
private const ulong fc_tag = 0xfc010203040506cf;
private const int buffer_size = 128*1024;
/// <summary>
/// 检验两个byte数组是否相同
/// </summary>
/// <param name="b1">byte数组</param>
/// <param name="b2">byte数组</param>
/// <returns>true-相等</returns>
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;
}
/// <summary>
/// 创建rijndael symmetricalgorithm
/// </summary>
/// <param name="password">密码</param>
/// <param name="salt"></param>
/// <returns>加密对象</returns>
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;
}
/// <summary>
/// 加密文件随机数生成
/// </summary>
private static randomnumbergenerator rand = new rngcryptoserviceprovider();
/// <summary>
/// 生成指定长度的随机byte数组
/// </summary>
/// <param name="count">byte数组长度</param>
/// <returns>随机byte数组</returns>
private static byte[] generaterandombytes(int count)
{
byte[] bytes = new byte[count];
rand.getbytes(bytes);
return bytes;
}
/// <summary>
/// 加密文件
/// </summary>
/// <param name="infile">待加密文件</param>
/// <param name="outfile">加密后输入文件</param>
/// <param name="password">加密密码</param>
public static void encryptfile(string infile, string outfile, string password)
{
using(filestream fin = file.openread(infile),
fout = file.openwrite(outfile))
{
long lsize = fin.length; // 输入文件长度
int size = (int)lsize;
byte[] bytes = new byte[buffer_size]; // 缓存
int read = -1; // 输入文件读取数量
int value = 0;
// 获取iv和salt
byte[] iv = generaterandombytes(16);
byte[] salt = generaterandombytes(16);
// 创建加密对象
symmetricalgorithm sma = cryptohelp.createrijndael(password, salt);
sma.iv = iv;
// 在输出文件开始部分写入iv和salt
fout.write(iv,0,iv.length);
fout.write(salt,0,salt.length);
// 创建散列加密
hashalgorithm hasher = sha256.create();
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();
}
}
}
/// <summary>
/// 解密文件
/// </summary>
/// <param name="infile">待解密文件</param>
/// <param name="outfile">解密后输出文件</param>
/// <param name="password">解密密码</param>
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 = cryptohelp.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("文件大小不匹配");
}
}
}
}
// 调用
public class testclass
{
string mypassword = "test_password_~!@#";
string myplainfile = "test.txt";
string myencryptedfile = "test.encrypted";
string mydecryptedfile = "test.decrypted";
[stathread]
static void main()
{
cryptohelp.encryptfile(myplainfile, myencryptedfile, mypassword);
cryptohelp.decryptfile(myencryptedfile,mydecryptedfile, mypassword);
}
}
- · 利用.NET的File控件上传文件的最终解决方案(个人版)
- · 如何把图片、声音等存储到sql中
- · MS-SQL server数据库开发精典技巧
- · 全文索引—CONTAINS语法
- · 获得所有表信息的SQL语句
- · .NET扫描远程计算机注册表
- · 利用JS获取IE客户端IP及MAC的实现
- · 简单而又复杂的ASP.NET编程模型
- · C#2.0终于有了?:便捷判断的单分支版
- · SQL Server 2005 Data Mining简介
- · ASP.NET控件开发之
- · ASP.NET中用哪种方式表格化数据
- · .NET平台下几种SOCKET模型的简要性能供参考
- · 使用 XML 模板 (MSSQL手册)
- · 使用带批注的 XDR 架构创建 XML 视图
- · 在XPath查询中指定轴(转自MSSQL手册)
- · JavaScript极速狂飙:CSS样式表的背景渲染效率
- · javascript应用:实现复选框全选/全不选切换
- · JavaScript极速狂飙:大容量字符型数组的快速检索
- · JavaScript极速狂飙:组合拼接字符串的效率
- · 图片自动缩小的js代码,用以防止图片撑破页面
- · PHP漏洞中的战争
- · automation服务器不能创建对象
- · Oracle数据库的备份及恢复策略研究
- · PHP程序加速探索之脚本执行速度测试
- · PHP中路径问题的解决方案
- · 学以致用 驳“ASP低能论”
- · 另类扩展名同样执行ASP
- · 语言决不是语法的不同之.NET 版本计算表达式的值
- · ASP中实现的类似URLEncode的编码函数及对应解码函数
- · 数据对象扩展成默认组件 PHP开发小组发布PHP5.1.0
- · ASP.NET 揭秘 ASP.NET页面的结构
- · 关于Sql server数据库日志满的快速解决办法
- · PHP+MySQL分页显示示例分析
- · ORACLE SQL性能优化系列(九)
- · ORACLE SQL性能优化系列(七)
- · ORACLE SQL性能优化系列(八)
- · JSP渐进学习教程4
- · ORACLE SQL性能优化系列(三)
- · ORACLE SQL性能优化系列(二)
- · ORACLE SQL性能优化系列(四)
- · ORACLE SQL性能优化系列(五)
- · ORACLE SQL性能优化系列(六)
- · ORACLE SQL性能优化系列(一)
- · JSP渐进学习教程7
- · JSP渐进学习教程6
- · JSP渐进学习教程5
- · JSP渐进学习教程9
- · JSP渐进学习教程8
- · 用多活动结果集优化ADO.NET2.0数据连接
- · PHP 5.0 的变化与PHP 6.0 展望
- · C#中从HTML生成DOM TreeView的代码
- · C#下从HTML文件生成DOM树
- · JSP渐进学习教程1
- · JSP渐进学习教程2
- · C#中的委托与事件[翻译]
- · 2分法-通用存储过程分页(top max模式)版本
- · 怎样获得Sqlserver 2000得实例列表和运行在一个实例上得数据库列表
- · 利用WWF进行ASP.NET程序开发
- · ASPImage组件的实现过程

