private void DecryptData(object fileParam) { File_Info fi = (File_Info)fileParam; //填充后的长度 long file_length = fi.FileLength + ((fi.FileLength % 16 == 0) ? 0 : (16 - fi.FileLength % 16)); long read_offset = 0; long write_offset = 0; //需要读取的长度 int read_size = File_Buffer_Size; int write_size = File_Buffer_Size; while (true) { //如果是最后一个分块则修改size if (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") || new FileInfo(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 (Exception ex) { this.Dispatcher.Invoke(new Action(() => { WriteLog(ex.ToString()); WriteLog("数据块解密过程出错"); snackbar.MessageQueue.Enqueue("数据块解密过程出错"); //终止传输 try { socketRecFile.Shutdown(SocketShutdown.Both); socketRecFile.Close(); socketRecFile = null; } catch (Exception e) { WriteLog(e.ToString()); WriteLog("停止接收 " + new FileInfo(fi.FileName).Name); snackbar.MessageQueue.Enqueue("停止接收" + new FileInfo(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"); this.Dispatcher.Invoke(new Action(() => { WriteLog(new FileInfo(fi.FileName).Name + " 解密完毕,正在计算校验值"); snackbar.MessageQueue.Enqueue(new FileInfo(fi.FileName).Name + "解密完毕"); progressBar_recFile.IsIndeterminate = false; })); //计算校验值 string file_hash = null; using (MD5 md5Hash = MD5.Create()) { FileStream fs = new FileStream(fi.FileName, FileMode.Open, FileAccess.Read); byte[] hash = md5Hash.ComputeHash(fs); file_hash = Convert.ToBase64String(hash); } //回送消息 TransCtrl_Message tm = new TransCtrl_Message(Status_Flag.Transmit_Over, DateTime.Now, file_hash, 0); socketConn.Send(Message2Byte(tm)); this.Dispatcher.Invoke(new Action(() => { WriteLog(new FileInfo(fi.FileName).Name + " 的本地校验值为" + file_hash); WriteLog("发送 " + new FileInfo(fi.FileName).Name + " 的校验值"); snackbar.MessageQueue.Enqueue("等待对方校验"); })); break; } } }
private void SendFile(object fileParam) { File_Info fi = (File_Info)fileParam; socketSendFile = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(((IPEndPoint)socketConn.RemoteEndPoint).Address, 8089); try { socketSendFile.Connect(iep); } catch { this.Dispatcher.Invoke(new Action(() => { WriteLog("传输端口无响应"); snackbar.MessageQueue.Enqueue("传输端口无响应"); })); } this.Dispatcher.Invoke(new Action(() => { WriteLog("开始发送 " + new FileInfo(fi.FileName).Name); snackbar.MessageQueue.Enqueue("开始发送 " + new FileInfo(fi.FileName).Name); })); long offset = 0; this.Dispatcher.Invoke(new Action(() => { progressBar_sendFile.Minimum = 0; progressBar_sendFile.Maximum = fi.FileLength; button_sendFile.IsEnabled = false; })); while (true) { //读取文件块 byte[] Read_buffer = FileRead(fi.FileName, offset, File_Buffer_Size); int length = Read_buffer.Length; offset += length; //加密文件块 byte[] Send_Buffer = DataCrypto.Encrypt(Read_buffer, AES); try { length = socketSendFile.Send(Send_Buffer); } catch (Exception ex) { this.Dispatcher.Invoke(new Action(() => { WriteLog(ex.ToString()); WriteLog("传输连接已断开"); snackbar.MessageQueue.Enqueue("传输连接已断开,停止发送 " + new FileInfo(fi.FileName).Name); })); break; } this.Dispatcher.Invoke(new Action(() => { progressBar_sendFile.Value = offset; })); if (offset >= fi.FileLength) { this.Dispatcher.Invoke(new Action(() => { WriteLog(new FileInfo(fi.FileName).Name + "发送完毕"); snackbar.MessageQueue.Enqueue(new FileInfo(fi.FileName).Name + "发送完毕"); socketSendFile.Shutdown(SocketShutdown.Both); socketSendFile.Close(); socketSendFile = null; })); break; } System.GC.Collect(); } this.Dispatcher.Invoke(new Action(() => { button_sendFile.IsEnabled = true; })); System.GC.Collect(); }
private void button_genRandom_Click(object sender, RoutedEventArgs e) { //连接可用性判断 if (socketConn == null || !socketConn.Connected) { this.Dispatcher.Invoke(new Action(() => { snackbar.MessageQueue.Enqueue("无可用连接"); })); return; } //如果已经认证通过就不需要再验证了 if (IsAuthenticated) { this.Dispatcher.Invoke(new Action(() => { snackbar.MessageQueue.Enqueue("已认证通过,无需再次操作"); })); return; } //生成一个100000-999999随机数作为挑战值challenge_value //要求对方收到挑战值后,对称密钥加密回送应答 int challenge_value = new Random().Next(100000, 999999); textBox_challengeValue.Text = challenge_value.ToString(); StringBuilder sBuilder = new StringBuilder(); byte[] hash; string Key; using (MD5 md5Hash = MD5.Create()) { //生成密钥 //Hash((1-challenge_value).ToString())作为预定密钥 hash = md5Hash.ComputeHash(Encoding.UTF8.GetBytes((1 - challenge_value).ToString())); foreach (byte b in hash) { 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_Message am = new Authen_Message(Status_Flag.Start_Challenge, DateTime.Now, challenge_value.ToString()); socketConn.Send(Message2Byte(am)); WriteLog("发起挑战,值为" + challenge_value.ToString()); WriteLog("生成预共享密钥"); snackbar.MessageQueue.Enqueue("发起挑战"); }