欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#实现数据包加密与解密实例详解

程序员文章站 2024-02-11 23:58:22
在很多项目中,为了安全安全考虑,需要对数据包进行加密处理,本文实例所述的即为c#加密代码,在应用开发中有很大的实用价值。说起数据包加密,其实对c#编程者来说,应该是一个基础...

在很多项目中,为了安全安全考虑,需要对数据包进行加密处理,本文实例所述的即为c#加密代码,在应用开发中有很大的实用价值。说起数据包加密,其实对c#编程者来说,应该是一个基础的技巧,是进行c#程序设计人员必须要掌握的技能。

c#实现加密功能的核心代码如下:

using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.windows.forms;
using system.threading;
using system.net;
using system.net.sockets;
using system.net.networkinformation;
using system.security.cryptography;
using system.io;
namespace encryptdatareport
{
  public partial class form1 : form
  {
    public form1()
    {
      initializecomponent();
    }
    #region 定义全局对象及变量
    private ipendpoint server;//服务器端
    private ipendpoint client;//客户端
    private socket mysocket;//套接字
    private endpoint clientip;//ip地址
    byte[] buffer, data;//接收缓存
    bool blflag = true;//标识是否第一次发送信息
    bool isport = false;//判断端口打开
    int sendnum1, receivenum1, disnum1; //记录窗体加载时的已发送\已接收\丢失的数据报
    int sendnum2, receivenum2, disnum2; //记录当前已发送\已接收\丢失的数据报
    int sendnum3, receivenum3, disnum3; //缓存已发送\已接收\丢失的数据报
    int port;//端口号
    #endregion
    //异步接收信息
    private void startlister(iasyncresult iaresult)
    {
      int num = mysocket.endreceivefrom(iaresult, ref clientip);
      string strinfo = encoding.unicode.getstring(buffer, 0, num);
      rtbcontent.appendtext("用户" + clientip.tostring());
      rtbcontent.appendtext(":");
      rtbcontent.appendtext("\r\n");
      rtbcontent.appendtext(decryptdes(strinfo, "mrsoftxk"));//对接收到的信息进行解密
      rtbcontent.appendtext("\r\n");
      mysocket.beginreceivefrom(buffer, 0, buffer.length, socketflags.none, ref clientip, new asynccallback(startlister), null);
    }
    //初始化已发送、已接收和丢失的数据报
    private void form1_load(object sender, eventargs e)
    {
      if (blflag == true)
      {
        ipglobalproperties netinfo = ipglobalproperties.getipglobalproperties();
        udpstatistics myudpstat = null;
        myudpstat = netinfo.getudpipv4statistics();
        sendnum1 = int32.parse(myudpstat.datagramssent.tostring());
        receivenum1 = int32.parse(myudpstat.datagramsreceived.tostring());
        disnum1 = int32.parse(myudpstat.incomingdatagramsdiscarded.tostring());
      }
    }
    //设置端口号
    private void button4_click(object sender, eventargs e)
    {
      try
      {
        port = convert.toint32(textbox4.text);
        checkforillegalcrossthreadcalls = false;
        buffer = new byte[1024];
        data = new byte[1024];
        server = new ipendpoint(ipaddress.any, port);
        client = new ipendpoint(ipaddress.broadcast, port);
        clientip = (endpoint)server;
        mysocket = new socket(addressfamily.internetwork, sockettype.dgram, protocoltype.udp);
        mysocket.setsocketoption(socketoptionlevel.socket, socketoptionname.broadcast, 1);
        mysocket.bind(server);
        mysocket.beginreceivefrom(buffer, 0, buffer.length, socketflags.none, ref clientip, new asynccallback(startlister), null);
        isport = true;//打开指定端口号
      }
      catch { }
    }
    //发送信息
    private void button2_click(object sender, eventargs e)
    {
      if (isport == true)//判断是否有打开的端口号
      {
        ipglobalproperties netinfo = ipglobalproperties.getipglobalproperties();
        udpstatistics myudpstat = null;
        myudpstat = netinfo.getudpipv4statistics();
        try
        {
          if (blflag == false)//非第一次发送
          {
            sendnum2 = int32.parse(myudpstat.datagramssent.tostring());
            receivenum2 = int32.parse(myudpstat.datagramsreceived.tostring());
            disnum2 = int32.parse(myudpstat.incomingdatagramsdiscarded.tostring());
            textbox1.text = convert.tostring(sendnum2 - sendnum3);
            textbox2.text = convert.tostring(receivenum2 - receivenum3);
            textbox3.text = convert.tostring(disnum2 - disnum3);
          }
          sendnum2 = int32.parse(myudpstat.datagramssent.tostring());
          receivenum2 = int32.parse(myudpstat.datagramsreceived.tostring());
          disnum2 = int32.parse(myudpstat.incomingdatagramsdiscarded.tostring());
          sendnum3 = sendnum2; //记录本次的发送数据报
          receivenum3 = receivenum2;//记录本次的接收数据报
          disnum3 = disnum2; //记录本次的丢失数据报
          if (blflag == true)//第一次发送
          {
            textbox1.text = convert.tostring(sendnum2 - sendnum1);
            textbox2.text = convert.tostring(receivenum2 - receivenum1);
            textbox3.text = convert.tostring(disnum2 - disnum1);
            blflag = false;
          }
        }
        catch (exception ex)
        {
          messagebox.show(ex.message, "提示信息", messageboxbuttons.ok, messageboxicon.information);
        }
        string str = encryptdes(rtbsend.text, "mrsoftxk");//加密要发送的信息
        data = encoding.unicode.getbytes(str);
        mysocket.sendto(data, data.length, socketflags.none, client);
        rtbsend.text = "";
      }
      else
      {
        messagebox.show("请首先打开端口!", "提示", messageboxbuttons.ok, messageboxicon.information);
        button4.focus();
      }
    }
    //清屏
    private void button1_click(object sender, eventargs e)
    {
      rtbcontent.clear();
    }
    //退出
    private void button3_click(object sender, eventargs e)
    {
      application.exit();
    }
    //按<ctrl+enter>组合键发送信息
    private void rtbsend_keydown(object sender, keyeventargs e)
    {
      //当同时按下ctrl和enter时,发送消息
      if (e.control && e.keyvalue == 13)
      {
        e.handled = true;
        button2_click(this, null);
      }
    }
    //聊天记录随时滚动
    private void rtbcontent_textchanged(object sender, eventargs e)
    {
      rtbcontent.scrolltocaret();
    }
    private static byte[] keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef };//密钥
    #region des加密字符串
    ///<summary>  
    ///des加密字符串  
    ///</summary>  
    ///<param name="str">待加密的字符串</param>  
    ///<param name="key">加密密钥,要求为8位</param>  
    ///<returns>加密成功返回加密后的字符串,失败返回源字符串</returns>  
    public string encryptdes(string str, string key)
    {
      try
      {
        byte[] rgbkey = encoding.utf8.getbytes(key.substring(0, 8));
        byte[] rgbiv = keys;
        byte[] inputbytearray = encoding.utf8.getbytes(str);
        descryptoserviceprovider mydes = new descryptoserviceprovider();
        memorystream mstream = new memorystream();
        cryptostream cstream = new cryptostream(mstream, mydes.createencryptor(rgbkey, rgbiv), cryptostreammode.write);
        cstream.write(inputbytearray, 0, inputbytearray.length);
        cstream.flushfinalblock();
        return convert.tobase64string(mstream.toarray());
      }
      catch
      {
        return str;
      }
    }
    #endregion
    #region des解密字符串
    ///<summary>  
    ///des解密字符串  
    ///</summary>  
    ///<param name="str">待解密的字符串</param>  
    ///<param name="key">解密密钥,要求为8位,和加密密钥相同</param>  
    ///<returns>解密成功返回解密后的字符串,失败返源字符串</returns>  
    public string decryptdes(string str, string key)
    {
      try
      {
        byte[] rgbkey = encoding.utf8.getbytes(key);
        byte[] rgbiv = keys;
        byte[] inputbytearray = convert.frombase64string(str);
        descryptoserviceprovider mydes = new descryptoserviceprovider();
        memorystream mstream = new memorystream();
        cryptostream cstream = new cryptostream(mstream, mydes.createdecryptor(rgbkey, rgbiv), cryptostreammode.write);
        cstream.write(inputbytearray, 0, inputbytearray.length);
        cstream.flushfinalblock();
        return encoding.utf8.getstring(mstream.toarray());
      }
      catch
      {
        return str;
      }
    }
    #endregion
  }
}

本例备有详细的注释,对于开发者而言应该不难理解,读者可以根据自身项目需要改进本例代码以符合自身应用需求。