由于工作需要,想把github作为公司的代码管理仓库,但是又不能公开代码,所以很简单,就是加密后再git上传。加密算法自然要选择效率高的,同时又是安全的。但是历史上好像这两项都是违背的,我说我要自己设计加密算法你们会不会喷我?但是我就是自己设计了。
思想很简单,就是用与明文相同位数的随机序列与明文异或!伪随机数发生器也是我自己diy的!如果你会因为这两点就怀疑我的加密算法的安全性,那先稍等一会儿。这个伪随机数发生器是用混沌方程当中的最简单的单峰映射(logstic map): xn+1=a*xn*(1-xn) , 这个可以看wikipedia 的英文版介绍:https://en.wikipedia.org/wiki/Logistic_map 其中说到:The relative simplicity of the logistic map makes it a widely used point of entry into a consideration of the concept of chaos. A rough description of chaos is that chaotic systems exhibit a great sensitivity to initial conditions—a property of the logistic map for most values of r between about 3.57 and 4 (as noted above).
我曾用NIST的随机监测工具检测过经logistic map选取合适的 a 值后产生序列的随机性(要截取每个产生的数的小数点第五位以后的部分作为随机数),发现甚至比目前大多数伪随机算法都要好,甚至比安全学领域中使用的一些伪随机算法还好。而且最大的优点是,人家速度快。
于是,这是一个可以高度自己定制的伪随机数发生器,a值只要选在3.57~4之间就行。于是选取的a不同,用于加密的算法也就变了(算法没变,但相当于变了)。这个加密方法类似于一次一密,所以不可能从对密文的分析中找出破解办法,因为密文是随机的。因此破解办法是暴力的方法,但是每个人使用的加密算法都可以不同,毕竟改一个a值太简单。另外就是xn的初始值,这也就是加密时的密钥。初始值需要时在(0,1)之间的任何值,但不包括0和1. 递推后产生的值也一直处于该区间内。
采用暴力破解法,复杂度取决于xn的有效数字。double类型的数有16~17位的有效数字,因此密钥的复杂度大概是1016,约相当于253,也就是说该加密算法密钥长度是53位。额,首先,我认为这已经足够了,因为没人知道我的加密算法,即使我把算法公之于众,因为我还可以改a的值。其次,在加密中,是借钱xn的第5~8位数与Unicode异或,我完全可以改成与第12~16位啊。即便如此,我们还可以任意的加长递推运算的有效数字位数,虽然这会带了效率上的缺失。你完全可以使用50位甚至更高精度的浮点数,50位复杂度就可以达到1050,相当于2165~2170位密钥长度。总之,这是一个没有限制的的算法。要是量子计算机来了,暴力破解100位的密钥长度的该算法需要1秒,那么就可以采用10000位啊,搜索域增加了1010000-10100,反正时间还是指数增长……
算法本来加密输出是乱码的,后来改为输出Unicode数字码,这样网络兼容性更好(不会因为乱码中空格漏掉一个而全都解密不了)。不说了,贴python代码:
import os # -*- coding:utf-8 -*- import tkinter as tk import tkinter.messagebox import tkinter.ttk as ttk import os class Window: def __init__(self,root): self.label=ttk.Label(root, text=‘Input PassWord: ‘) self.entry=ttk.Entry(root,show=‘*‘) self.passw=‘‘ if os.path.exists(‘important_file‘): with open(‘important_file‘) as f: self.passw=f.readline() else: self.label.pack(side=‘left‘,anchor=‘nw‘,pady=10) self.entry.pack(side=‘top‘, after=self.label,anchor=‘nw‘,pady=10) pass self.button=ttk.Button(root, text=‘解密‘, command=self.Decipher) self.button.pack(side=‘top‘,anchor=‘nw‘) self.button=ttk.Button(root,text=‘加密‘,command=self.Encrypt) self.button.pack(side=‘top‘,anchor=‘nw‘) self.texti=tk.Text() #self.texti.insert(1.0,‘Input something here.‘) self.texto=tk.Text() self.texti.pack(side=‘top‘,anchor=‘nw‘,pady=20) self.texto.pack(side=‘top‘,anchor=‘nw‘,pady=20) self.inputext=‘‘ def Decipher(self): if not self.passw: self.passw=self.entry.get() if not self.passw: tk.messagebox.showinfo(‘Error‘,‘Why not enter the password?‘); return self.inputext=self.texti.get(1.0,tk.END) if self.inputext==‘‘: tk.messagebox.showinfo(‘Error‘,‘What is your inputext?‘); return if not self.inputext[0].isdigit(): tk.messagebox.showinfo(‘Error‘,‘Be sure that your input starts with digits!‘); return self.__crack() def Encrypt(self): if not self.passw: self.passw=self.entry.get() if not self.passw: tk.messagebox.showinfo(‘Error‘,‘Why not enter the password?‘); return self.inputext=self.texti.get(1.0,tk.END) if self.inputext==‘‘: tk.messagebox.showinfo(‘Error‘,‘What is your inputext?‘); return if self.inputext[0].isdigit(): if not tk.messagebox.askyesno(‘Note‘,‘Are you sure you are encrypting digits?‘): return self.__encrypt() def __crack(self): ‘‘‘indicates that the input text should be number only ‘‘‘ self.texto.delete(1.0,tk.END) listp=list(self.passw) p=[ord(x) for x in listp] pw=1 for x in p: pw=x*pw pws=‘0.‘+str(pw) pw=float(pws) listin=self.inputext.split(‘ ‘) for x in listin: pw=pw*(1-pw)*3.93699989893668722729139042 pws=str(pw) pivot= int(pws[-6:-3]) if x==‘‘: self.texto.insert(tk.INSERT,‘ ‘) elif x[0]==‘\n‘: self.texto.insert(tk.INSERT,‘\n‘) else: self.texto.insert(tk.INSERT,chr(int(x)^pivot)) if not os.path.exists(‘important_file‘): self.__writepw() pass def __encrypt(self): ‘‘‘turn string into number string every word takes one lines‘‘‘ self.texto.delete(1.0,tk.END) listin=list(self.inputext) listp=list(self.passw) p=[ord(x) for x in listp] pw=1 for x in p: pw=x*pw pws=‘0.‘+str(pw) pw=float(pws) for x in listin: pw=pw*(1-pw)*3.93699989893668722729139042 pws=str(pw) pivot= int(pws[-6:-3]) self.texto.insert(tk.INSERT,str(ord(x)^pivot)+‘ ‘) pass def __writepw(self): with open(‘important_file‘,‘w‘) as f: f.write(self.passw) os.system(‘attrib +s +r +h +a important_file‘) root=tk.Tk() root.title(‘OUR CIPHER TALK‘) window=Window(root) root.mainloop() 代码是python3的,需要tkinter,windows上能运行,其它系统未知。这个只是加密解密结合的程序,博主根据这个算法写的将github改造为私密仓库的代码在我的github地址上:https://github.com/AdaJass/privatesolution