Python笔记:带路党可用的公用信道加密工具(rsa+rc4)

  • 2019 年 11 月 22 日
  • 筆記

应该如何保障信息安全呢?

使用PGP或者GPG是很好的方法。但是,本着DIY精神,今天在网上东拼西凑了一个基于RC4和RSA的加密工具(玩具)。

1 用法

使用在前需要生成密钥对。使用generateKeys.py生成。对方的公钥保存到keys文件夹,自己的私钥保存到项目根目录。

rsa加密相互使用对方的公钥对原文加密,把密文传输到对方,由对方使用配套的私钥进行解密。如果要双方能相互通信,则必须互相拥有对方的公钥。

加密

1 双击main.pyw,出现窗口。

2 将要加密的字符串如“今天天气真好”,ctrl + c 复制到剪贴板。

3 激活main.pyw窗口,按快捷键shitf + x。

4 此时窗口闪动一长串字符串,很快又变成原字符串“今天天气真好”。这意味着密文已经生成成功了。并且保存到了剪贴板。

5 到需要发送的地方如微信或者邮件,按ctrl + v。此时将粘贴一大串密文。发送给对端即可。

解密

双击main.pyw 出现窗口。

把密文ctrl + c 复制到剪贴板。

如果你有权限,被解密的原文自动出现在main.pyw窗口中。(也可以使用shift + v快捷键)

配置

settings.py

email用来配置你自己的私钥邮件地址。用来解密用。

usermaps 用来配置发送的密文能被谁解密。注意,keys文件夹下必须有对应的公钥。

下载

rsacommu.zip

2 文件组织如下:

D:.

│  [email protected]

│  cryptObj.py

│  generatekey.py

│  main.pyw

│  settings.py

│  test.py

│      

├─bll

│      encrypt.py

│      rc4.py

│      __init__.py

└─keys

        [email protected]

        [email protected]

3 代码

main.pyw

#coding:utf-8  import time  import Tkinter as tk  from bll import encrypt as enc  import cryptObj  import thread  import time    class MainApplication(tk.Frame):      def __init__(self, parent, *args, **kwargs):          tk.Frame.__init__(self, parent, *args, **kwargs)          self.parent = parent               S = tk.Scrollbar(root)          T = tk.Text(root, height=4)          S.pack(side=tk.RIGHT, fill=tk.Y)          T.pack(side=tk.LEFT, fill=tk.Y)          S.config(command=T.yview)          T.config(yscrollcommand=S.set)             self.MainText = T          parent.bind("<Shift-Key-X>",self.EncryptClipBoard)          parent.bind("<Shift-Key-V>",self.DecryptClipBoard)          self.MainText.pack()          thread.start_new_thread (self.monitor_clipboard,())        def EncryptClipBoard(self,event):          clip_text = self.parent.clipboard_get()          msg = cryptObj.Messages(clip_text)          clip_text = msg.ToString()                    self.MainText.delete('1.0', tk.END)          self.MainText.insert(1.0,clip_text)          self.parent.clipboard_clear()          self.parent.clipboard_append(clip_text)            def DecryptClipBoard(self,event):          clip_text = self.parent.clipboard_get()          msg = cryptObj.Messages(clip_text)          clip_text = msg.DecryptJson()          self.MainText.delete('1.0', tk.END)          self.MainText.insert(1.0,clip_text)          self.parent.clipboard_clear()          self.parent.clipboard_append(clip_text)                def monitor_clipboard(self):          oldstr = ""          while True:              time.sleep(1)              clip_text = self.parent.clipboard_get()              if isinstance(clip_text,str) and oldstr != clip_text:                  if clip_text.startswith('{"userpwd'):                      oldstr = clip_text                      msg = cryptObj.Messages(clip_text)                      clip_text = msg.DecryptJson()                      self.MainText.delete('1.0', tk.END)                      self.MainText.insert(1.0,clip_text)                                                  if __name__ == "__main__":      root=tk.Tk()      root.geometry("600x400")      main = MainApplication(root)      main.pack(side="top", fill="both", expand=True)      root.mainloop()

settings.py

#coding:utf-8  email = "[email protected]"  usermaps = ["[email protected]","[email protected]"]

generatekey.py

#coding:utf-8  import rsa    email = raw_input("input email:")  # 先生成一对密钥,然后保存.pem格式文件,当然也可以直接使用  pubkey, privkey = rsa.newkeys(1024)    pub = pubkey.save_pkcs1()  with open(email+'-pub.pem', 'w') as f:      f.write(pub)     pri = privkey.save_pkcs1()  with open(email+'-pri.pem', 'w') as f:      f.write(pri)

cryptObj.py

#coding:utf-8  from bll import encrypt as enc  from bll import rc4  import os  import settings  import json  import base64    class Messages(object):      def __init__(self,msg):          self.UserMaps = settings.usermaps          self.Message = msg        def GetRndStr(self):              rndByte = os.urandom(6)          b64Str = base64.urlsafe_b64encode(rndByte)          return b64Str        def ToString(self):          rndpwd = self.GetRndStr()          class TempMsgs(object):              pass          msg = TempMsgs()          msg.userpwd = {}            for k in self.UserMaps:              msg.userpwd[k] = enc.EncryptRsa(rndpwd,k)            rc4enc = rc4.rc4(rndpwd)          msg.value = rc4enc.encode(self.Message)            jsons = json.dumps(msg.__dict__)          return jsons        def DecryptJson(self):          jsons = json.loads(self.Message)          userpwds = jsons['userpwd']          encValue = jsons["value"]            for k in userpwds:              if k == settings.email:                  encpwd = userpwds[k]                  rndpwd = enc.DecryptRsa(encpwd,k)                    rc4enc = rc4.rc4(rndpwd)                  return rc4enc.decode(encValue)          return ""

bll/encrypt.py

#coding:utf-8  import settings  import rsa  import base64    main_email = settings.email  dirname = "keys/"         # 用公钥加密、再用私钥解密  def EncryptRsa(text,email):      with open(dirname + email + '-pub.pem') as publickfile:          p = publickfile.read()          pubkey = rsa.PublicKey.load_pkcs1(p)        crypto = rsa.encrypt(text, pubkey)      b64Str = base64.urlsafe_b64encode(crypto)      return b64Str    def DecryptRsa(crypto,email):      with open(email + '-pri.pem') as privatefile:          p = privatefile.read()          privkey = rsa.PrivateKey.load_pkcs1(p)            text = base64.urlsafe_b64decode(str(crypto))      return rsa.decrypt(text, privkey)

bll/rc4.py

#coding=utf-8    import sys,os,hashlib,time,base64  class rc4:      def __init__(self,public_key = None,ckey_lenth = 16):          self.ckey_lenth = ckey_lenth          self.public_key = public_key or 'none_public_key'          key = hashlib.md5(self.public_key).hexdigest()          self.keya = hashlib.md5(key[0:16]).hexdigest()          self.keyb = hashlib.md5(key[16:32]).hexdigest()          self.keyc = ''        def encode(self,string):          string = string.encode('utf-8')          self.keyc = hashlib.md5(str(time.time())).hexdigest()[32 - self.ckey_lenth:32]          string = '0000000000' + hashlib.md5(string + self.keyb).hexdigest()[0:16] + string                  self.result = ''          self.docrypt(string)          return self.keyc + base64.b64encode(self.result)        def decode(self,string):          self.keyc = string[0:self.ckey_lenth]          string = base64.b64decode(string[self.ckey_lenth:])          self.result = ''          self.docrypt(string)          result = self.result          if (result[0:10] == '0000000000' or int(result[0:10]) - int(time.time()) > 0) and result[10:26] == hashlib.md5(result[26:] + self.keyb).hexdigest()[0:16]:              return result[26:]          else:              return None        def docrypt(self,string):          string_lenth = len(string)          result = ''          box = list(range(256))          randkey = []            cryptkey = self.keya + hashlib.md5(self.keya + self.keyc).hexdigest()          key_lenth = len(cryptkey)            for i in xrange(255):              randkey.append(ord(cryptkey[i % key_lenth]))            for i in xrange(255):              j = 0              j = (j + box[i] + randkey[i]) % 256              tmp = box[i]              box[i] = box[j]              box[j] = tmp            for i in xrange(string_lenth):              a = j = 0              a = (a + 1) % 256              j = (j + box[a]) % 256              tmp = box[a]              box[a] = box[j]              box[j] = tmp              self.result += chr(ord(string[i]) ^ (box[(box[a] + box[j]) % 256]))