源码地址:

(55条消息) 基于Python语言、RSA非对称加密的IRC聊天室客户端源码与应用程序-Python文档类资源-CSDN文库

1 研究背景和现状

IRC是Internet Relay Chat 的英文缩写,中文一般称为互联网中继聊天。它是由芬兰人Jarkko Oikarinen于1988年首创的一种网络聊天协议。经过十年的发展,目前世界上有超过60个国家提供了IRC的服务。IRC的工作原理非常简单,您只要在自己的PC上运行客户端软件,然后通过因特网以IRC协议连接到一台IRC服务器上即可。它的特点是速度非常之快,聊天时几乎没有延迟的现象,并且只占用很小的带宽资源。所有用户可以在一个被称为\"Channel\"(频道)的地方就某一话题进行交谈或密谈。每个IRC的使用者都有一个Nickname(昵称)。

IRC用户使用特定的用户端聊天软件连接到IRC服务器,通过服务器中继与其他连接到这一服务器上的用户交流,所以IRC的中文名为"因特网中继聊天"。

IRC的最大特点是实现了在线实时交谈,速度快、功能多的优点使它比电子邮件或新闻组等联络沟通方式更具吸引力。IRC可以设置单独的频道,在这个频道内,输出的文字可供所有人都看到。这样,来自世界不同角落的人能同时得到有关信息。而如果是两个人之间的单独交谈,甚至可以不用通过服务器,以保证谈话的保密性。随着网络带宽的增加和技术的发展,现在有一些IRC不仅可以传输文字信息,还能传输声音或图像信息,这样的功能就更强了。

2 研究历史和现状

在网上我们查到了这样一段话,认为能够很好地概括IRC的发展与现状:

因为本人研究IRC时间较长,鉴于目前的发展状况,近两年来都有如下的思考。

目前IRC也仅有263还算是IRC了,但它也仅是人数上处于一个领先的地位,从其发展与聊天人群来看,已经再也不是2000-2002年的IRC了。从2000年来看,sina,sohu,tom,163,几乎所有大网站的web聊天室都是基于IRC的,为什么就突然不行了呢?

其实我认为IRC到目前为止,还是一个很好的东西,只不过它固有模式不适合在中国发展。由于游戏产业的突飞猛进以及qq,msn等音视频支持的即时通信工具的出现,IRC在一夜之间跌入低谷,从此原本喜欢IRC的用户一下子分流到其它工具之上。而提供IRC服务的服务商们也没有精力继续维持,直接导致了现在这个窘况的出现。

我认为,IRC在中国的应用应该转变它的角色了,如果再将它做为一个聊天服务来提供的话是肯定不行的。但它优秀的网络结构及传输协议还是可以扩展到其它行业去的。因为现有很多行业或是网站它需要的一个用户与服务器的长连接来实现适时数据的交换,这个时候,IRC还是很有用途的。比如说网站的在线客户服务系统(目前已有公司专门提供了),基于即时通讯的电子商务(alibaba已经走在前头了,当我有此想法的时候,alitalk也没有出现),网络与现场相结合的拍卖系统等,很多的应用都可以用IRC来实现,但这就需要我们对IRC的服务器端及协议要有非常熟悉的了解,还需要我们能写出自已的客户端软件或是web applet、flash等web客户端。其实用扩展IRC server协议写出基于flash的网络休闲游戏都是有可能的。当然由于IRC协议的纯文本发送模式的限制,它不可以用在保密性要求较高的项目中。  所以,我还是相信IRC会有它的用武之地。当然我也只是研究研究罢了,没有超前的商业头脑去想出一个什么好的产品投入应用,如果你有更好的应用项目,那就告诉我吧,也许我可以帮你实现。

综上所述:IRC在2000初的时候是红极一时的,主要是由于它的便利性和快捷性,但是随着社交网络的发展,博客、论坛等形式的出现,再加上FaceBook、QQ等之后聊天软件的相继涌现,IRC的低私密性、安全性和简陋的界面等局限性相继放大逐渐退出了历史舞台。

3 研究相关工作

在准备实现IRC协议与系统研制之前,我们首先查了相关IRC的概念、理论、应用等实际的相关话题,使得我们对于IRC(Internet Relay Chat)本身有了更加深刻的理解。

之后为了使用Python语言实现对于IRC系统的研制,我们查阅了相关的开源代码。包括但不限于IRC系统机器人的调制,RSA针对聊天内容的加密功能与解密,Python语言多线程功能的实现等等。

4 研究目标、内容和关键问题

4.1 研究目标:

设计IRC客户端,实现基于IRC协议的多人聊天室,并对传输的信息进行加密

4.2 实验原理:

服务器与客户端之间通过IRC协议进行通信,在IRC协议中,用户可以加入到频道Channel中,在频道中发送消息,频道中的所有人都能接收到信息。

但大多数情况下,我们需要希望发送的消息是保密的,只有发送端和接收端能够得到消息。因此,需要对消息进行加密,在这里我们使用RSA非对称加密。

RSA非对称加密方法中,存在一对密钥,分别为公钥和私钥。其中公钥公开,私钥秘密保存。在RSA加密通信中,发送端和接收端各有一对密钥,且不相同。发送信息时,发送端用接收端的密钥进行加密,接收端用自身保存的私钥进行解密。由于能够解密的私钥只保存在接收端,因此只有接收端能解开加密内容,如此实现加密。

4.3 实验重点

(1)客户端能够连接到指定的IRC服务器,并能够加入到用户指定的频道Channel,能够向频道中发送消息,并且能够同时接收来自IRC服务器的消息以及其他用户在频道中发送的消息。

(2)通过RSA加密算法对发送消息进行加密,能够实现与相同频道中的指定用户进行加密通信,其他用户无法解密。

(3)设计界面,能够便于用户操作,同时收集用户输入的信息,为用户提供输出信息。

4.4 难点分析

(1)与IRC服务器相连接,需要根据IRC协议配置好发送消息的格式,能够与IRC服务器建立连接。

(2)收发的同步进行,用户发送消息和接收来自服务器的消息是同时进行的过程,应当能够同时进行,保证通信的实时性。

(3)RSA加密算法的实现,需要更新加密密钥,保证每一个客户端生成的一对密钥各不相同,同时需要与加密通信的对象进行连接,互相发送公钥。客户端用接收端的公钥对发送信息进行加密,用自己的私钥对接收信息进行解密。

5 研究方案和技术路线

(1)在本项目中,我们通过调用irc库中的函数,与IRC服务器建立连接,并且加入到特定的频道中。

(2)设计另一个接收服务器消息的线程,使得用户在操作客户端,例如发送信息的同时,能够接收来自服务器的消息。

(3)利用PyOpenssl库,每一个客户端在开启时自动产生一对独一无二的密钥,保存私钥,公开公钥。利用rsa库,客户端用接收端的公钥对发送信息进行加密,用自己的私钥对接收信息进行解密。

(4)利用PyQt5设计用户界面,并且编写每一个控件的槽函数。

6 系统设计与实现

6.1 系统总体设计

主要功能和性能

本项目编写的客户端程序,能够提供登录界面,用户可以输入用户名、频道和服务器地址,输入完毕后系统能够自动连接到该服务器的指定频道。

在菜单中,有登录、选择频道、连接到服务器、断开连接、退出的功能,能够方便用户使用。

用户能够在频道中群发消息,也能够通过PRIVCONNECT name与用户名为name的用户进行一对一加密通信。

系统能够实现RSA密钥的生成与更新,保证每一个客户端的一对密钥是独一无二的,私钥只存在用户的电脑上。不同客户端的密钥不相同。发送加密信息时,用接收端的公钥对发送信息进行加密;接收时,用客户端保存的自身私钥对接收信息进行解密。

6.2 关键功能模块实现

在程序一开始,系统利用PyOpenssl库,生成一对密钥,将私钥以变量的形式在程序中保存,不进行任何传输,公钥写入rsa_public_key.pem文件中。

设计一个receive类,建立receive类的一个新的线程,在receive.run()函数中,客户端接收服务器发送的消息,并且进行判断和处理,判断是否为建立私密通信请求,是否为公钥消息,是否为加密消息,以及普通消息。

在客户端(client1)发送建立私密连接请求,即PRIVCONNECT client2时,client1与client2互相发送自身的公钥,存储为rsa_public_key2.pem。在发送加密消息时,调用rsa库中的函数,用对方的公钥即rsa_public_key2.pem,对发送消息进行加密。同时接收加密消息时,用自身的私钥pri_key对接收的加密消息进行解密。

7 部分代码

from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox,QWidget
from PyQt5.QtGui import QTextCursor
import ircchat
import Crypto
import rsa
import socket
import threading
import RSA
import name
import choose
import sys
global server
global channel
global connected
global botnick
global registered
global friend
global private
private=0   #建立私密连接后private=1,否则为0
friend=""   #建立私密连接中,对方的匿名
botnick = "pythonxz"    #自身的匿名即用户名
channel ="#casual"      #频道
server = "open.ircnet.net"       #服务器网站
global rsaUtil
global pri_key
Crypto.key_inital()                 #在文档中新建两个公钥文件,进行初始化
pri_key = Crypto.generate_key()     #产生公钥和私钥
rsaUtil = RSA.RsaUtil(pri_key)      #初始化rsaUtil加密解密类irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #defines the socket
def send_private():    #在建立私密连接后进行加密发送print("sending private\n")if connected==1 and registered==1:global channelglobal botnickprint ("sending\n")global rsaUtilglobal friendui.label.setText("加密连接到:"+friend+"于频道"+channel)message_encode=rsaUtil.encrypt_by_public_key(('<'+botnick+'>' + ui.lineEdit.text()).encode())   #使用对方公钥加密print(message_encode)irc.send(('PRIVMSG ' + channel + ' :' + "CODED"+str(message_encode.decode())+"\r\n" ).encode())  #发送加密消息ui.textEdit.append('<'+botnick+'>' + ui.lineEdit.text() + '\r\n')ui.lineEdit.clear()ui.textEdit.moveCursor(QTextCursor.End)else:if connected==0:box=QMessageBox()box.setWindowTitle("警告")box.setText("没有连接到服务器,请点击文件->连接")reply=box.exec()else:box = QMessageBox()box.setWindowTitle("警告")box.setText("未登录,请点击文件->登录")reply = box.exec()
def send_public(): #没有建立私密连接时,不加密发送消息if connected==1 and registered==1:global privateif private==0:global channelglobal botnickprint ("sending public\n")text=ui.lineEdit.text()print(text)if text.find("PRIVCONNECT ")!=-1:   #判断是否为建立私密连接的指令print("private connecting:\n")t5 = text.split("PRIVCONNECT ")  # you can change t and to :)to5 = t5[1].strip()  # this code is for getting the first word after !higlobal friendfriend=to5print("CONNECTING WITH "+friend)irc.send(('PRIVMSG ' + channel + ' :' +"PRIVCONNECT "+friend+" "+botnick + "\r\n").encode())send_public_key()else:   #正常发送公开消息print("normal sending\n")irc.send(('PRIVMSG ' + channel + ' :' + '<'+botnick+'>' + text + "\r\n").encode())ui.textEdit.append('<'+botnick+'>' + text + '\r\n')ui.lineEdit.clear()ui.textEdit.moveCursor(QTextCursor.End)else:send_private()else:if connected==0:box=QMessageBox()box.setWindowTitle("警告")box.setText("没有连接到服务器,请点击文件->连接")reply=box.exec()else:box = QMessageBox()box.setWindowTitle("警告")box.setText("未登录,请点击文件->登录")reply = box.exec()
def send_public_key():  #发送自身公钥print("sending public key\n")publickfile = open('rsa_public_key.pem', 'r')p = publickfile.read()print(p)p = p.replace("\n","*-----*")irc.send(('PRIVMSG ' + channel + ' :'+"PUBLICKEY "+botnick+p+"\r\n").encode())publickfile.close()
class recieve (threading.Thread):  #接收类def run(self):while 1:    #puts it in a loopif connected==1:global channelglobal friendtext=irc.recv(2040)  #receive the textprint ((text).decode())   #print text to consoleif text.find(('PRIVMSG ' + channel + ' :' +"PRIVCONNECT "+botnick+" ").encode())!=-1: #判断是否为私密连接指令t = text.split(('PRIVMSG ' + channel + ' :' +"PRIVCONNECT "+botnick+" ").encode())  # you can change t and to :)to = t[1].strip()  # this code is for getting the first word after !hifriend=to.decode()ui.textEdit.append("connecting with friend:"+friend+"\n")send_public_key() #发送自己的公钥if text.find(('PRIVMSG ' + channel + ' :'+"PUBLICKEY "+friend).encode())!=-1:  #判断是否为对方的公钥信息t = text.split(('PRIVMSG ' + channel + ' :' + "PUBLICKEY "+friend).encode())  # you can change t and to :)to = t[1].strip()  # this code is for getting the first word after !hito_str=to.decode()to_str=to_str.replace("*-----*","\n")print("receive key\n")ui.textEdit.append("receving keys")print(to_str)ui.textEdit.append(to_str)pubfile = open('rsa_public_key2.pem', 'w')  #存储对方的公钥pubfile.write(to_str)pubfile.close()print("write over\n")global rsaUtilglobal pri_keyrsaUtil = RSA.RsaUtil(pri_key)      #利用对方的公钥准备为信息加密print("generate rsa\n")global privateprivate=1ui.textEdit.append("generate rsa\n")if text.find(('PRIVMSG ' + channel + ' :'+"CODED").encode()) !=-1: #判断是否为加密信息t = text.split(('PRIVMSG ' + channel + ' :'+"CODED").encode())  # you can change t and to :)to = t[1].strip()  # this code is for getting the first word after !hiprint(to)message_decode=rsaUtil.decrypt_by_private_key(to)   #利用自己的私钥解密ui.textEdit.append(str(message_decode.decode())+"\r\n")ui.textEdit.moveCursor(QTextCursor.End)else:   #正常接收非加密消息if text != 0:ui.textEdit.append((text).decode())ui.textEdit.moveCursor(QTextCursor.End)if text.find(('PING').encode()) != -1:                          #check if 'PING' is foundirc.send(("PONG " + str(text.split() [1]) + "\r\n").encode()) #returnes 'PONG' back to the server (prevents pinging out!)if text.find((':!hi').encode()) != -1:  # you can change !hi to whatever you wantt = text.split((':!hi').encode())  # you can change t and to :)to = t[1].strip()  # this code is for getting the first word after !hiirc.send(('PRIVMSG ' + channel + ' :Hello ' + str(to) + '! \r\n').encode())
thread1 = recieve()
thread1.setDaemon(True)
def irc_connect():      #与IRC服务器建立连接if registered==1:global channelglobal botnickglobal serverprint("connecting to:" + server)ui.textEdit.append("connecting to:" + server)irc.connect((server, 6667))  # connects to the serverglobal connectedconnected=1ui.label.setText("已连接到"+channel+"频道")irc.send(("USER " + botnick + " " + botnick + " " + botnick + " :This is a fun bot!\n").encode())  # user authenticationirc.send(("NICK " + botnick + "\n").encode())  # sets nickirc.send("PRIVMSG nickserv :iNOOPE\r\n".encode())  # authirc.send(("JOIN " + channel + "\n").encode())  #join the chan    connected=1else:box = QMessageBox()box.setWindowTitle("警告")box.setText("未登录,请点击文件->登录")reply = box.exec()
def join_channel(): #显示选择频界面Widget2.show()
def register():     #显示登录界面Widget.show()
def user_info():    #用户信息收集global botnickglobal registeredglobal channelchannel=ui2.lineEdit_3.text()botnick=ui2.lineEdit.text()registered=1global serverserver=ui2.lineEdit_2.text()Widget.close()MainWindow.show()irc_connect()
def choose_channel(): #加入指定频道global channelchannel=ui3.lineEdit.text()irc.send(("JOIN " + channel + "\n").encode())  # join the chan    connected=1ui.label.setText("已连接到" + channel + "频道")Widget2.close()
def disconnect(): #与服务器断开连接global connectedirc.send(("quit" + "\r\n").encode())connected=0
def irc_quit(): #退出程序MainWindow.close()Widget.close()Widget2.close()exit()
if __name__ == '__main__':app = QApplication(sys.argv)MainWindow = QMainWindow()Widget=QWidget()Widget2=QWidget()ui = ircchat.Ui_MainWindow()ui2=name.Ui_Form()ui3=choose.Ui_Form()ui.setupUi(MainWindow)ui2.setupUi(Widget)ui3.setupUi(Widget2)Widget.show()connected=0registered=0ui.lineEdit.returnPressed.connect(lambda:send_public())ui.action_C.triggered.connect(lambda:irc_connect())ui.action_C_2.triggered.connect(lambda:join_channel())ui.action_E.triggered.connect(lambda:register())ui.action_D.triggered.connect(lambda:disconnect())ui.action_Q.triggered.connect(lambda:irc_quit())ui2.pushButton.pressed.connect(lambda:user_info())ui2.lineEdit_2.setText("open.ircnet.net")ui2.lineEdit_3.setText("#casual")ui3.pushButton.pressed.connect(lambda:choose_channel())thread1.start()sys.exit(app.exec_())

完整代码所在地址:(55条消息) 基于Python语言、RSA非对称加密的IRC聊天室客户端源码与应用程序-Python文档类资源-CSDN文库

基于Python语言、RSA非对称加密的IRC聊天室客户端相关推荐

  1. C语言实现DES加密的简单聊天室

    目录 目录 概述 前言 运行截图 一些问题 正文 服务器端 客户端 头文件 tables.h bool.h 参考资料 概述 前言   我是用linux系统中的vim进行编辑   用gcc进行编译    ...

  2. [源码和文档分享]基于java语言的C/S模式网络聊天室软件

    一 需求分析 采用C/S模式,基于TCP协议编程的方式,使得各个用户通过服务器转发实现聊天的功能 分为三大模块:客户端模块.服务器端模块和公共辅助类模块 客户端模块的主要功能: 登陆功能:用户可以注册 ...

  3. Python代码实现MD5、AES对称加密和RSA非对称加密以及OpenSSl实践

    1.MD5加密算法 1.1 MD5加密的特点 不可逆运算 对不同的数据加密的结果是定长的32位和16位字符(不管文件多大都一样) 对相同的数据加密,得到的结果是一样的(也就是复制). 抗修改性 :信息 ...

  4. 易语言PHP非对称加密,RSA非对称加密通信源码

    RSA非对称加密通信 非对称加密是非常安全的一类加密算法 TXQQ客户Duan的通信也用了椭圆曲线非对称加密(ECC) 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(priva ...

  5. java RSA非对称加密详解

    简介 RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年首次公布,当 ...

  6. python写web自动化_Web接口开发与自动化测试——基于Python语言

    目 录∣ V 目 录 第1 章 Python 学习必知 ........................................................................ ...

  7. Atitit RSA非对称加密原理与解决方案

    Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制  3 1.4. 基于rsa的授权验证机器码 4 1.5. ...

  8. jemeter python接口自动化测试平台_WEB接口开发与自动化测试基于PYTHON语言PDF_Python教程...

    资源名称:WEB接口开发与自动化测试 基于PYTHON语言 PDF 内容简介: <Web接口开发与自动化测试--基于Python语言>以接口测试为主线,以Web开发为切入点,全面介绍了We ...

  9. Springboot+RSA非对称加密

    这是百度百科对(对称加密丶非对称加密)的解释: (1)对称加密算法在加密和解密时使用的是同一个秘钥. (2)非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称 ...

最新文章

  1. 使用C# 3.0编译器编译 Asp.Net 项目代码
  2. Yann Lecun最新演讲:机器怎样进行有效学习?
  3. 程序员必知的操作系统知识点
  4. 初始化懒惰关系以及何时使用它们的5种方法
  5. crontab 定时任务
  6. js layui跳转页面_layui自己添加图片按钮并点击跳转页面的例子
  7. python怎么读发音百度翻译-用python实现百度翻译的示例代码
  8. silverlight 3 blend3最新版本 破解方法
  9. Python 读取/存储 yaml 文件
  10. android基础复习笔记——3.登录授权、TCP/IP、HTTPS原理
  11. dos模拟器即时存档工具_DOS游戏运行模拟器 DOSBox0.72 1.2MB DOS游戏必备
  12. H3C路由器-内/外网用户通过公网IP访问内部服务器
  13. MAXENT模型的生物多样性生境模拟与保护优先区甄选、自然保护区布局优化评估及论文写作技巧
  14. C++中的堆内存、栈内存和静态内存
  15. 计算机上显示F怎么取消,联想笔记本如何关闭Fn功能键 怎么取消电脑的f
  16. 编程自学网站(赶紧收藏)
  17. C++11右值引用、移动语义、完美转发详解
  18. 我们的空间是圆的么——基于Poicare的宇宙模型浅谈
  19. 对接抖音开发之售后消息实时通知订单部分退款
  20. 百度地图离线开发demo-测距(vue+百度地图3.0+百度瓦片)

热门文章

  1. MT8516方案开发,MT8516芯片平台资料
  2. CSS盒子模型-小白学习中
  3. 数据库操作(23道基础实践题)
  4. 基于高效查找表的无记忆非线性自适应基带预失真架构
  5. Delphi下使用Sato打印机
  6. Java程序实现一个空调的类,基于jsp的空调电费管理系统-JavaEE实现空调电费管理系统 - java项目源码...
  7. MongoDB初级部分
  8. 天津事业编计算机类考试内容,天津事业单位考什么
  9. 非标行业的类标准产品经验
  10. Kafka与zk的关系及连接参数bootstrap.server的正确理解