回 帖 发 新 帖 刷新版面

主题:[原创]文件加密程序[含原码-原理说明]

[size=2][color=0000FF]编程教学
一个简单的文件加密解密程序.

    如果你是高手,请跳过.

    本文的程序目标是一个文件加密程序.这是应一位网友要求而做的一个软件原型.要求如下:
    项目:文件加密解密程序
    要求:
    1.可对任意文件进行加密解密操作,包括EXE,RAR,TXT等等.最终效果为使得原始数据不能识别,或原程序不能运行.
    2.加密操作必须可逆,加密后文件通过程序解密操作后.必须与原文件一致.保证要使用加密信息时文件还可以还原使用.
    3.要有较高的安全性.使得加密密码不易破解.加密后密文不易解读.保证原文件加密后的数据安全性.
    4.使得密文与加密算法尽量无关.即达到这样的效果:你得到加密后的文件与加密程序原代码,知道如何加密,你也解不开密文.
    5.易操作.使得加密与解密在代码上与工作效率上都容易做到.不至于使编程过于困难.或是代码过于复杂.

    对于这种问题.书上已经有很多现成的例子可供使用.比如代换法:使用一个固定的字符代换原文中指定的字符.这要求有一个自定义的编码表.里面含有原文中每个单位信息的对照参考.并且,此表中要包含所有原文中可能出现的字符.此方法可以加密英文文本.比如用C换A,用F换I等等.此表大概包含100多个对照序列即可对英文所有出现的字符编码.[大小写字母共52个,数字10个,特殊符号等].但此方法有一致命缺陷,如果被人知道的你的编码表.密文就被破解了.还有其它的现有的方法但不适用于本程序.比如MD5加密后不可逆,文件不能还原.BASE64也属于代换法的一种,只不过把字节重新拆分组合.每6B(位)加密成一个值.加密后文件比原来大三倍.并且很容易还原原文.等等.
    
    本文使用的是异或 XOR 加密.此方法很多书上都有介绍.原理是:一个值经过2次XOR异或操作后会还原原值.
    即: A=(A XOR B) XOR B
    基本思路为:读取输入密码(此密码由加密用户手工输入)放入变量S中.把S拆分成单个字符,并转换成对应的ASCii值.把所有密码字符对应的ASC值放入一个字节型数组PB()中,每个元素放一个值.这样数组PB就是密码的每位ASC值.加密时.把原文打开.一个字节一个字节的读入数据.每读入一个字节.都按顺序与密码数据PB中的一个值进行异或操作.操作后的结果做为密文写入密文文件中.直到原文件读取结束.在此过程中密码数组PB中的值按顺序依次与每个原文字节操作,若到PB结尾时,重新从PB开始处循环.这样加密不是很安全.因为密码很容易会被试出来.密码直接用于加密密文.在后面会提出解决方法.
    流程:
    1.开始
    2.从文本框读取密码放入变量S.
    3.循环拆分S,得到密码的ASC数值数组.
      示例:[注:此代码只做为参考]
      dim pb(0 to 32) as byte
      for i = 0 to len(s)-1
          pb(i)=ascii(mid(s,i+1,1))
      next i 
    4.打开文件 FS1 ,此文件为待加密的原始文件.
    5.打开文件 FS2 ,此文件为加密后的密文文件.
    6.使用VB中 GET 函数从文件 FS1 中读取一个字节数据.放入字节变量 X 中.此时X中含有一字节的原文信息.
    7.执行核心代码:
      DIM P AS BYTE
      P=X XOR PB(I)
      使X与密码中一个数值进行XOR异或操作.得到加密后字节P.其中:变量I在每次循环中增一,到PB上限时再重新计数.
    8.使用VB中 PUT 函数把P写入文件 FS2 中.
    9.原文是否到文件尾? 不是则返回第6步执行.是则继续.
    10.关闭文件 FS1,FS2.
    11.结束.

    从上面的流程中可以看出.由于XOR操作的性质:2次XOR可还原原值.可知加密函数与解密函数是一样的.只要对密文件进行上面流程的操作,文件就会被还原.文件还原是否正确依赖于密码的值.另从最初的项目要求也看出符合题目要求:对字节操作可以加密任何一种文件数据.加密后的数据肯定与原值不同,可以起到保护原文信息的目的.XOR操作可逆,文件会准确的还原到原始的样子,加密后的数据由于进行了每个字节的变异.肯定显示的都是乱码.并且,密文以最基本的字节流方式依赖于密码值.密码不对肯定不能得到原文.
    
    但是.从以上的加密过程中也可以看出.密文很容易破解.密码也会被试出来.你可以试一下加密一个全是相同的字母的文本文件.很快会找出规律.并且,密码如果有一部分是正确的话原文也会显示出来(只是显示不全而已),比如你加密时使用了一个长度为16位的密码.解密时你把密码的最后一位换成其它字母.也就是说,解密密码与加密密码只有最后一位不同.你会发现.还原后的文件与原文98%以上都一样.即:密码的安全性不可靠.可以通过试验.把密码一个一个的试出来.

    下面的工作就是加强密码的安全性.也就是说要达到这样的效果:你的密码如果与原密码有一个特征不一致(字符不对.或是长度不对)都不能解密出原文中的任何一个字节.就是说:你解密密码与原密码哪怕99.9%一样.你也不可能得到原文的任何一个部分.
   
    要实现这样的效果很容易想到加密中的不可逆算法.如MD5.但MD5不能直接对原文进行加密.否则密文不能还原.思路是这样:把加密密码S先进行MD5运算,获得密码的MD5散列.再用这个MD5值对原文进行加密.这样可以想到,只要密码有一点点的变化.得出的MD5肯定会大相径庭.解密时,由错误的密码得到一个与加密时完全不同的一个加密MD5值,用此数值解密后得到的肯定都是垃圾数据.这里简单说明一下MD5:MD5是把加密目标看成是一个长的字节序列.经过MD5运算后会得出一个与此长字节序列相对应的一个唯一的特征指纹.结果是一个16个字节的BYTE型数组.把此数组的每一字节转化为由2位16进制数表示的字符.这样就得到了MD5的32位值.取中间的16位则为MD5的16位值.加密函数有现成的可供参考,不做赘述.这里,我们直接使用内存中MD5的原始16位数据.

    流程:
    1.开始
    2.从文本框读取密码放入变量S.
    3.dim M() as byte = MD5(s).获得密码的MD5散列值.运行后,M中含有16个字节的S的MD5值.
    4.打开文件 FS1 ,此文件为待加密的原始文件.
    5.打开文件 FS2 ,此文件为加密后的密文文件.
    6.使用VB中 GET 函数从文件 FS1 中读取一个字节数据.放入字节变量 X 中.此时X中含有一字节的原文信息.
    7.执行核心代码:
      DIM P AS BYTE
      P=X XOR M(I)    注意这里,参与加密运算的不是密码本身,而是密码的MD5.而此值是与密码密切相关的.
      使X与M中一个数值进行XOR异或操作.得到加密后字节P.其中:变量I在每次循环中增一,到M上限时再重新计数.
    8.使用VB中 PUT 函数把P写入文件 FS2 中.
    9.原文是否到文件尾? 不是则返回第6步执行.是则继续.
    10.关闭文件 FS1,FS2.
    11.结束.
    
至此.程序已经可以达到要求了.对于数据的安全性.可以想到,你如果是一个一个密码去试,肯定会试出来(对于暴力破解是免不了的)但我们可以设一个很长的密码,增加破解的难度.想要一次性猜对密码除非他是神仙.另一方面由于使用MD5的16个字节加密.使用像UE这样的软件很容易看出来文件中的规律,但是想要一个一个字节的试出来原文的内容也不是件易事.另外,我们还可以使用密码的特征来增加加密难度.比如使用密码长度数值参与加密,对已经MD5过的密码再进行置换操作等等.使得密文没有规律.

至此文件加密程序完成.已经写好的代码在附件中.程序使用Visual Studio 2005 VB.Net 编写.运行时,Vista/Server2008可直接运行.其它系统:XP SERVER2003等需要先装.NET FRAMEWORK 2.0方可运行.如需要VB6.0版本的程序联系我.

本文中没有实际运行代码.只提供了一种解决问题的思路.有不明白的朋友欢迎一起讨论.

由于本人也是菜鸟.本文中难免有错误与疏漏.望朋友们指正.并提出宝贵的程序改进建议.

另:寻破解密文的高手.因为程序难免存在破解漏洞.如果你能找到加密中的漏洞,并可以在没有密码的情况下成功得到原文.请把附件包中的CREAK ME.TXT中的原文解密,并说明破解方法.希望大家一起讨论.[/color][/size]

回复列表 (共10个回复)

沙发

唉...
没人搭理俺.....

555

板凳

工程错误.

3 楼

什么错误?
说详细一点.

程序代码已经通过测试.

不是VB.
是VB.NET

如果不能运行.那是你没装.NET FRAMEWORK 2.0

4 楼

知道,我还想看看你为什么要打开一个本地的TCP连接!~ 还是说程序自己打开的!?~



转换报告 - EC_FileEncoding
转换时间:2009年2月10日20:40


解决方案: EC_FileEncoding
文件名 状态 错误 警告 
EC_FileEncoding.sln 已转换 0 0 
转换问题 - EC_FileEncoding.sln: 
成功转换解决方案 
 
1 个文件 已转换: 1
未转换: 0 0 0 


转换设置 
解决方案文件: C:\Documents and Settings\xxxxxxxx\My Documents\EC_FileEncoding\EC_FileEncoding.sln 



一般有两个文件转换版本. 请解决.

5 楼

你是用的VS2008么?
我是用的2005的.

不知道你为会还要转换.

关于为什么要开TCP我也不清楚.
代码已经在里面了.

我自己测试功能正常.

编程环境:

家:
Windows Server 2008
Visual Studio 2005 VB.net
.Net Framework 3.5

单位:
Windows Server 2003
Visual Studio 2005 VB.net
.Net Framework 2.0

我是2套机器轮换着用的.

6 楼

本来想发在.NET区的.
看了看...
VB.NET里面一个人都没有.
帖子都放的长毛了.
所以就把.NET程序发这里来了.

随后我会发在我机器上运行的截图.

7 楼

= =;

8 楼

你好:能不能够提供一份6.0版本的代码啊?
我的邮箱xuehu90@126.com
谢谢

9 楼

原创最伟大

10 楼

伟大

我来回复

您尚未登录,请登录后再回复。点此登录或注册