Chinaunix首页 | 论坛 | 博客
  • 博客访问: 589206
  • 博文数量: 752
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(752)

文章存档

2011年(1)

2008年(751)

我的朋友

分类:

2008-10-13 16:48:33

模拟信息加密流程图简介

作者:



  Encryption_Demo 代码模拟了图一和图二的流程图内容,但仅仅只是模拟,谈不上什么应用;其应用过程限于程序间的传递过程,没有涉及到网络间数据传输,所以仅仅是模拟其过程而已。



图一 采用安全认证的信息加密流程图



图二 采用安全认证技术的信息解密过程图



图三 采用安全认证的信息加密流程图文字说明


图四 采用安全认证技术的信息解密过程图的文字说明

  Encryption_Demo 代码没有什么新奇之处。发布的目的在于使大家了解“采用安全认证的信息加密流程图”的运作过程。代码,大家可以下载看一看。下面我要说的是,最主要的工作体现在字节数组的偏移量的计算上。比如在本程序中采用MD5散列,其散列值固定长度16个字节;采用DES算法分组加密,其Key和IV字节数都为8个字节;采用RSA进行签名,签名长度固定为128个字节,而加密结果的长度呢,我们要加密的字节数组长度为128+8+8 = 144,那么RSA非对称加密后的字节数长度就为1152个字节长度。那么,在第一个流程图中,合并后的整个密文数据字节长度,我们知道不固定,可是它的第一部分和第三部分长度是固定的(再强调一次,我们这里使用DES分组加密算法,MD5散列函数,RSA方法签名和加密,下面分析结果也都是建立这基础上的)。比如:

加密后的会话密文 —— RsaEncryptData :1152
摘要签字 —— CombinData : 144
我们可以获得整个要截密文件的长度

string fileName = OpenFile("请打开要解密的文件:");
FileStream fs = new FileStream(fileName,FileMode.Open,FileAccess.Read);

  (int)fs.Length - 1152-144 运算结果就是中间密文---EncryptionDate 的长度。解密中间密文后,紧接着就要处理时间戳啦。我们分析时间戳的字节数组组成吧:

文件散列长度 :16
接收时间 :23
签名长度 :128
总共长度 :167

  既然知道这些字节数组的组成,你该知道怎么做了吧?关于处理接收时间戳的处理上,有点要注意的:

public static byte [] GetTimeNow()
{
	//这样转化成的格式为:2004-11-09 13:04:28-108 23个字节
	DateTime now = DateTime.Now;
	System.Text.UTF8Encoding utf = new System.Text.UTF8Encoding();
	
	string month = null ;
	if(now.Month<10)
		month = "0"+now.Month.ToString();
	else
		month = now.Month.ToString();
	
	string day = null;
	if(now.Day<10)
		day = "0" + now.Day.ToString();
	else
		day = now.Day.ToString();
	
	string millisecond = null;
	if(now.Millisecond<10)
		millisecond = "00"+now.Millisecond.ToString();
	if(now.Millisecond>=10&&now.Millisecond<=99)
		millisecond = "0" + now.Millisecond.ToString();
	if(now.Millisecond>=100)
		millisecond = now.Millisecond.ToString();
	string FullFormatTime = now.Year.ToString() +
                                 "-" + month + "-" + 
                                 day + " " + 
                                 now.ToLongTimeString() + "-" + millisecond ;
	//比如:2004-11-09 13:04:28-108
	return utf.GetBytes( FullFormatTime );         
} 		
  这样处理后的结果是接收时间精确到毫秒,且固定字节长度为23个字节。我们把第一个流程图的结果写进文件中去(其路径与你要加密的原始明文在同一目录下,主要是为了储存的方便),而流程图二的解密结果则保存在bin\Release目下。这样解密时需要读取文件,这里提供了两种方法,第一种把文件内容读取到一个数组里面,另外一种是需要时直接从文件中提取的指定的字节数组。第一种方法把文件内容读取到一数组,解密时分解数组,使用Buffer.BlockCopy( )函数分解既可。比如,从fileContent数组中偏移量1152处开始复制“length”长度字节复制到一个新的数组“Encrypt_Two”中去。
int length = (int)fs.Length-1296;// -1152-144 ; //密文的长度AllEncryptedData
Encrypt_Two = new byte[ length ];
Buffer.BlockCopy(fileContent,1152,Encrypt_Two,0,length);

而采用第二种方法:

Encrypt_One = new byte[1152];
fs.Read(Encrypt_One,0,1152); 

  这样直接从文件流开始位置读取 1152 个字节到数组“Encrypt_One”中。但如果要提取字节不是从起点开始,那就需要设置文件流的位置:

//读取加密的明文
int length = (int)fs.Length-1296;// -1152-144 ; //密文的长度 AllEncryptedData
Encrypt_Two = new byte[ length ]; 
fs.Position = 1152 ; //文件流偏移位置了1152个字节
fs.Read(Encrypt_Two,0,length);      
  注意了fs.Read()方法内参数的表示啦,而这样表达:fs.Read(Encrypt_Two,length,length),程序会报告文件偏移量出现错误。
  需要说明的是,在设计代码时,把主窗体程序所能使用到的功能都封装到一个类里面,且所有被使用到的函数都是静态类型,便于使用上的方便。测试程序,需要用到三对钥匙:发送者(A)、接收者(B)和时间戳服务器(DTS)的各自的私钥和公钥。基于流程图一,你使用时间戳服
务器私钥一次,A的私钥两次,B的公钥一次。基于流程图二,你使用时间戳服务器公钥一次,A的公钥两次,B的私钥一次。至于测试所用到钥匙,你可以在压缩包Encryption Demo\bin\Release目录可以看到三个文件夹,里面分别存放着发送者(A)、接收者(B)和时间戳服务器(DTS)的各自的钥匙。当然你也可以自己生成钥匙,点击“产生一对钥匙”按钮,见下图:



  那么产生的钥匙你可以在程序的bin\Release目录下找到。那么怎么使用本程序呢,你可以使用已经准备好的三对公钥,按照下图图示即可:
1、“打开文件”—选择你要加加密的文件,点击下面的“提交到DTS服务中心...”按钮。



2、点击选项卡“加密步骤二”,直接点下面的按钮“开始以上步骤”,这中间会要求你打开钥匙文件,别搞错啊。



3、最后一个选项卡,“开始解密”按钮,你也知道怎么做吧 :)



注:这中间会出现对话框要求你打开密钥文件,可别选择错啊,要不,不会出现预期的目标。之所以这样做,本身就要你注意区分密钥与密钥的不同(要不,不能体现本程序的编写的意图。你说呢~!?J)。当然大家也可以自己使用更好对称加密算法、散列函数,比如 Rijndeal 对称加密算法、SHA512等,那就需要你重新计算这其中的字节偏移量啦(可有偿定制)。时间不充分哦,代码和注释写得有些乱,请凑合着看啦 J Bye_Bye !

代码下载地址: Demo.rar
 
--------------------next---------------------

阅读(306) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~