




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
-1-文件安全传输系统课程设计报告目录一、课题任务11.1开发环境11.2主要任务1二、总体设计12.1程序框架12.2设计流程22.3验证模型32.4传输模型3三、详细设计43.1基础协议43.2组件实现53.3用户界面16四、课题总结194.1遇到的问题及解决方法194.2实验分工204.3心得体会21一、课题任务1.1开发环境 VisualStdio2017.Net4.5WPF1.2主要任务 实现通过网络进行文件加密传输,要求进行密钥协商,及大文件的传输,程序使用C#进行开发,有良好的用户界面。二、总体设计2.1程序框架 2.2设计流程安全安全文件传输系统数据绑定前后端链接安全数据绑定前后端链接安全传输功能整合WPF前端开发WPF前端开发传输组件的实现安全组件的实现密钥协商协议设计加密解密密钥协商协议设计加密解密算法选择与实现传输协议设计界面设计 2.3验证模型验证方受验方验证方受验方由随机数生成密钥并加密应答值解密应答比对应答是否有效,发送结果 认证成功则使用共享密钥建立安全链路2.4传输模型接受方发送方接受方发送方传输连接的建立发送文件请求是否接收开始发送Block[0]Block[1]Block[2]…Block[n]接收完毕请求校验校验并告知结果断开连接三、详细设计3.1基础协议 =1\*GB2⑴基于CHAP的密钥协商由传输请求方发起请求,接收方发起挑战,挑战值为随机生成的6位整数。该挑战值即为密钥生成密钥,生成算法为:Key=Hasℎ请求方收到挑战值后,对其用预协商的算法进行变换,同时生成密钥,变换算法为:f之后生成响应值:Response=接收方收到回应后同本地计算的预期回应值比对,相同则验证成功,同时将Key作为传输密钥。 =2\*GB2⑵基于AES的文件分块加密文件传输采用AES加密,密钥由基于CHAP的密钥协商生成,使用System.Security.Cryptography.AesCryptoServiceProvider生成AES服务实例,配置AES.Key=Encoding.ASCII.GetBytes(Key);AES.IV=Encoding.ASCII.GetBytes(Key.Substring(0,16));AES.Padding=PaddingMode.Zeros;保存加密服务实例。文件加密采用分块加密,设置块缓冲区的大小为File_Buffer_Size(默认为1MB),每次对一个文件块进行加密,最后一块若需填充则已设置的填充方式为准。 =3\*GB2⑶自定义的传输控制协议 由发送方发起文件传输请求Transmit_Request;接受方选择是否接收Transmit_Allow或Transmit_Cancel;发送方发送完毕后等待接收方的接收完成;接收方接收并解密完成后计算文件MD5值Transmit_Over;发送方收到接收完毕的消息及MD5值后,比对本地文件的MD5值,告知接收端VerifySuccess或VerifyFailed;3.2组件实现 =1\*GB2⑴认证协议的实现服务端发起挑战部分代码://生成一个100000-999999随机数作为挑战值challenge_value//要求对方收到挑战值后,对称密钥加密回送应答intchallenge_value=newRandom().Next(100000,999999);textBox_challengeValue.Text=challenge_value.ToString();//用string储存密钥StringBuildersBuilder=newStringBuilder();byte[]hash;stringKey;using(MD5md5Hash=MD5.Create()){//生成密钥//Hash((1-challenge_value).ToString())作为预定密钥hash=md5Hash.ComputeHash(Encoding.UTF8.GetBytes((1-challenge_value).ToString()));foreach(bytebinhash){ //哈希值本身为16字节,AES的密钥需要32字节,将其转换为小写的16进制sBuilder.Append(b.ToString("x2"));}Key=sBuilder.ToString();textBox_key.Text=sBuilder.ToString(); //计算响应值 //Hash(Hash(challenge_value.ToString()))为应答hash=md5Hash.ComputeHash(Encoding.UTF8.GetBytes(challenge_value.ToString()));hash=md5Hash.ComputeHash(hash);}//计算响应密文(期望响应)AES=DataCrypto.GenAesCryptoServiceProvider(Key);//字符串采用base64编码ExpertResponse=Convert.ToBase64String(DataCrypto.Encrypt(hash,AES));textBox_expertResponse.Text=ExpertResponse;//生成挑战消息并发送Authen_Messageam=newAuthen_Message(Status_Flag.Start_Challenge,DateTime.Now,challenge_value.ToString());socketConn.Send(Message2Byte(am));客户端响应挑战部分代码://生成密钥,过程与服务端一致//收到的挑战值显示于textBox_challengeValueStringBuildersBuilder=newStringBuilder();byte[]hash;using(MD5md5Hash=MD5.Create()){hash=md5Hash.ComputeHash(Encoding.UTF8.GetBytes((1-challenge_value).ToString()));foreach(bytebinhash){sBuilder.Append(b.ToString("x2"));}Key=sBuilder.ToString();textBox_key.Text=sBuilder.ToString(); }//////////////////////////////////////////////////////////////////////////////////////////////////////生成响应值StringBuildersBuilder=newStringBuilder();byte[]hash;using(MD5md5Hash=MD5.Create()){//计算响应值hash=md5Hash.ComputeHash(Encoding.UTF8.GetBytes(textBox_challengeValue.Text));hash=md5Hash.ComputeHash(hash);}//生成AES服务实例AES=DataCrypto.GenAesCryptoServiceProvider(Key); //计算预期响应stringResponse=Convert.ToBase64String(DataCrypto.Encrypt(hash,AES));textBox_genResponse.Text=Response;Authen_Messageam=newAuthen_Message(Status_Flag.Response_Challenge,DateTime.Now,Response);socketConn.Send(Message2Byte(am));服务器端验证响应部分代码://如果收到的响应值与预期响应值相同则认证成功,否则失败if(ExpertResponse==am.Extend){ //生成认证成功的消息并发送Authen_Messageau=newAuthen_Message(Status_Flag.Authen_Success,DateTime.Now,null);socketConn.Send(Message2Byte(au)); //标记为已认证IsAuthenticated=true; //开一个传输控制线程,进入传输控制阶段Threadtrd=newThread(TransControl);trd.IsBackground=true;trd.Start();break;}else{ //生成认证失败的消息并发送Authen_Messageau=newAuthen_Message(Status_Flag.Authen_Failed,DateTime.Now,null);socketConn.Send(Message2Byte(au));}客户端收到认证成功消息后进入传输控制阶段,失败则退出验证阶段。=2\*GB2⑵AES加密类的构造//有32字节的密钥(字符串形式)生成AES服务提供者实例publicstaticAesCryptoServiceProviderGenAesCryptoServiceProvider(stringKey){AesCryptoServiceProviderAES=newAesCryptoServiceProvider();//配置密钥AES.Key=Encoding.ASCII.GetBytes(Key);//配置向量为密钥的前16字节AES.IV=Encoding.ASCII.GetBytes(Key.Substring(0,16)); //配置填充模式为填充0AES.Padding=PaddingMode.Zeros;returnAES;} //加密明文字节数组,返回密文字节数组,参数为明文与AES实例publicstaticbyte[]Encrypt(byte[]cipher,AesCryptoServiceProviderAES){ //初始化一个流存放密文MemoryStreamms=newMemoryStream(); //创建加密转换实例ICryptoTransformAESencrypt=AES.CreateEncryptor(); //构建加密流CryptoStreamcryptostream=newCryptoStream(ms,AESencrypt,CryptoStreamMode.Write); //将明文字节数组写入加密流cryptostream.Write(cipher,0,cipher.Length);//将缓冲区内数据立即加密,并清除缓冲区cryptostream.FlushFinalBlock();//将密文由流转为字节数组byte[]code=ms.ToArray(); //关闭流cryptostream.Close();ms.Close();returncode;} //解密密文字节数组,返回明文字节数组,参数为密文与AES实例publicstaticbyte[]Decrypt(byte[]code,AesCryptoServiceProviderAES){MemoryStreamms=newMemoryStream(); //创建解密转换实例ICryptoTransformAESdecrypt=AES.CreateDecryptor();CryptoStreamcryptostream=newCryptoStream(ms,AESdecrypt,CryptoStreamMode.Write);cryptostream.Write(code,0,code.Length);cryptostream.FlushFinalBlock();byte[]cipher=ms.ToArray();cryptostream.Close();ms.Close();returncipher;} =3\*GB2⑶传输协议的实现消息标志设置publicenumStatus_Flag{Start_Challenge=1,Response_Challenge,Authen_Success,Authen_Failed,Time_Out,Transmit_Request,Transmit_Allow,Transmit_Cancel,Transmit_Over,VerifySuccess,VerifyFailed}认证消息结构publicstructAuthen_Message{ //消息标志publicStatus_FlagFlag; //时间戳publicDateTimeTime; //强制填充字符串至256位,保证包长一致,方便消息数据的封包解包[MarshalAs(UnmanagedType.ByValTStr,SizeConst=256)] //扩展字段publicstringExtend; //构造函数publicAuthen_Message(Status_Flagflag,DateTimet,stringstr){this.Flag=flag;this.Time=t;this.Extend=str;} //返回结构信息的方法publicstringMessageInfo(){return"{\nFLAG:"+Flag.ToString()+"\nTIME:"+Time.ToLongTimeString()+"\nExten:"+Extend+"\n}";}}传输控制消息结构publicstructTransCtrl_Message{publicStatus_FlagFlag;publicDateTimeTime;[MarshalAs(UnmanagedType.ByValTStr,SizeConst=256)] //文件名publicstringFileName; //文件长度publiclongFileLength;publicTransCtrl_Message(Status_Flagflag,DateTimet,stringfile_naem,longfile_length){this.Flag=flag;this.Time=t;this.FileName=file_naem;this.FileLength=file_length;}publicstringMessageInfo(){return"{\nFLAG:"+Flag.ToString()+"\nTIME:"+Time.ToLongTimeString()+"\nFileName:"+FileName+"\nFileLength:"+FileLength.ToString()+"\n}";}}传输控制协议部分代码 //如果对方接收文件if(tm.Flag==Status_Flag.Transmit_Allow){ //开辟线程发送文件ParameterizedThreadStartpts=newParameterizedThreadStart(SendFile);ThreadthreadWatch=newThread(pts);threadWatch.IsBackground=true; //SendFileInfo为待发送文件的文件路径及长度threadWatch.Start(SendFileInfo);} //如果对方取消接收文件if(tm.Flag==Status_Flag.Transmit_Cancel){this.Dispatcher.Invoke(newAction(()=>{WriteLog("对方拒绝接收");snackbar.MessageQueue.Enqueue("对方拒绝接收");})); //跳出接收消息的循环break;} //如果对方接收到文件并解密完毕if(tm.Flag==Status_Flag.Transmit_Over){//计算校验值stringfile_hash=null;using(MD5md5Hash=MD5.Create()){FileStreamfs=newFileStream(SendFileInfo.FileName,FileMode.Open,FileAccess.Read);byte[]hash=md5Hash.ComputeHash(fs);file_hash=Convert.ToBase64String(hash);} //Transmit_Over消息中的FileName字段用于储存哈希值 //如果本地计算的哈希值与对方哈希值一致,则校验成功if(file_hash==tm.FileName){//回送校验成功的消息TransCtrl_Messagetcm=newTransCtrl_Message(Status_Flag.VerifySuccess,DateTime.Now,null,0);socketConn.Send(Message2Byte(tcm));} //反之则不成功else{//回送消息TransCtrl_Messagetcm=newTransCtrl_Message(Status_Flag.VerifyFailed,DateTime.Now,null,0); socketConn.Send(Message2Byte(tcm));}文件发送方法部分代码//文件信息结构,包含文件路径和长度File_Infofi=(File_Info)fileParam;socketSendFile=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//传输端口默认为8089,接收端监听此端口,发送端一旦接入即开始发送IPEndPointiep=newIPEndPoint(((IPEndPoint)socketConn.RemoteEndPoint).Address,8089);try{socketSendFile.Connect(iep);}Catch{ //异常处理 //return;} //定义变量用来保存当前已接收的数据量longoffset=0;while(true){//读取文件块byte[]Read_buffer=FileRead(fi.FileName,offset,File_Buffer_Size);intlength=Read_buffer.Length;offset+=length; //加密文件块byte[]Send_Buffer=DataCrypto.Encrypt(Read_buffer,AES);try{length=socketSendFile.Send(Send_Buffer);}catch(Exceptionex){ //网络异常则停止发送break;} //如果超过或等于文件长度则停止发送if(offset>=fi.FileLength){break;} //回收内存System.GC.Collect();}接收文件部分代码File_Infofi=(File_Info)fileParam;//开始监听文件传送端口Socketsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);IPEndPointiep=newIPEndPoint(((IPEndPoint)socketConn.LocalEndPoint).Address,8089);socket.Bind(iep);socket.Listen(1);try{socketRecFile=socket.Accept(); //停止对端口的监听socket.Close();}catch{}//开一个线程进行解密,参数为文件信息ParameterizedThreadStartpts=newParameterizedThreadStart(DecryptData);Threadtrd=newThread(pts);trd.IsBackground=true;trd.Start(fi); //计算加密填充后的长度longfile_length=fi.FileLength+((fi.FileLength%16==0)?0:(16-fi.FileLength%16));longoffset=0;while(true){intlength=-1;byte[]buffer=newbyte[File_Buffer_Size];try{length=socketRecFile.Receive(buffer);}catch(Exceptionex){ //网络异常则停止接收break;} //设置读写锁进入写,将禁止所有读锁_rwlock.EnterWriteLock();FileWrite(fi.FileName+".tmp",offset,length,buffer);_rwlock.ExitWriteLock();offset+=length; //如果已经接收完毕,便停止接收if(offset>=file_length){ //重置套接字try{socketRecFile.Close();}catch(Exceptionex){}socketRecFile=null;}));break;}System.GC.Collect();}解密文件部分代码File_Infofi=(File_Info)fileParam;//填充后的长度longfile_length=fi.FileLength+((fi.FileLength%16==0)?0:(16-fi.FileLength%16));longread_offset=0;longwrite_offset=0;//需要读取的长度intread_size=File_Buffer_Size;//需要写入的长度intwrite_size=File_Buffer_Size;while(true){//如果是最后一个分块则修改sizeif(read_offset+File_Buffer_Size>file_length){read_size=(int)(file_length%(long)File_Buffer_Size);write_size=(int)(fi.FileLength%(long)File_Buffer_Size);} //开始接收while(true){//如果不足一块则等待if(!File.Exists(fi.FileName+".tmp")||newFileInfo(fi.FileName+".tmp").Length<read_offset+read_size){continue;}break;}_rwlock.EnterReadLock();byte[]Read_Buffer=FileRead(fi.FileName+".tmp",read_offset,read_size);_rwlock.ExitReadLock();read_offset+=read_size;byte[]Write_Buffer=null;try{Write_Buffer=DataCrypto.Decrypt(Read_Buffer,AES);}catch(Exceptionex){//终止传输try{socketRecFile.Shutdown(SocketShutdown.Both);socketRecFile.Close();socketRecFile=null;}catch(Exceptione){WriteLog(e.ToString());WriteLog("停止接收"+newFileInfo(fi.FileName).Name);snackbar.MessageQueue.Enqueue("停止接收"+newFileInfo(fi.FileName).Name);}break;} //写入解密后的文件FileWrite(fi.FileName,write_offset,write_size,Write_Buffer);write_offset+=write_size;if(write_offset>=fi.FileLength){//删除tmp文件File.Delete(fi.FileName+".tmp");//计算校验值stringfile_hash=null;using(MD5md5Hash=MD5.Create()){FileStreamfs=newFileStream(fi.FileName,FileMode.Open,FileAccess.Read);byte[]hash=md5Hash.ComputeHash(fs);file_ha
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 吉安职业技术学院《幼儿健康教育与活动指导》2023-2024学年第二学期期末试卷
- 吉林职业技术学院《基础医学总论二:病理生理学、病理学、药理学》2023-2024学年第一学期期末试卷
- 宁波卫生职业技术学院《大学生创新创业意识》2023-2024学年第二学期期末试卷
- 云南省昆明盘龙区联考2024-2025学年初三下学期开学考试(普通班)数学试题试卷含解析
- 湛江市高一上学期期末调研考试英语试题
- 企业财务成本管理培训
- 2025简约店面租赁合同
- 2025芦笋种植合同 管理资料
- 2025漯河市商品房买卖合同
- 2025房屋租赁合同有效期
- 艾滋病知识培训课件
- 0-3岁婴幼儿常见疾病与伤害防护知到智慧树章节测试课后答案2024年秋杭州师范大学
- 专题07 等差数列与等比数列(考点清单+知识导图+ 13个考点清单-题型解读)(原卷版)-25学年高二数学上学期期末考点大串讲
- 博士科研计划书模板
- 《Origin的使用方法》课件
- 2024年WPS计算机二级考试题库350题(含答案)
- 医疗设备仪器培训
- 2023中考道德与法治十大热点预测-2023年中考道德与法治考场速查宝典(部编版)
- 高中英语必背3500单词表(完整版)
- GB/T 44570-2024塑料制品聚碳酸酯板材
- 2024年新人教版五年级数学下册《教材练习20练习二十附答案》教学课件
评论
0/150
提交评论