@Lin--
2020-01-02T10:31:05.000000Z
字数 10674
阅读 412
ComSec
实现RSA加解密和签名功能。要求如下:
1、安全参数:1024 bits-2048bits
2、有简单的交互界面、或命令行操作
3、语言: Python、 C/C++、Java
4、平台:不限
5、加解密可以针对简单的字符文本;签名(验证签名)针对任意选择的文件。
本题用两个程序实现,第一个程序生成大素数和.
第二个程序实现加解密及签名(验证签名)功能。
'''# File : Get_PUPR.py# Author : Hongpei Lin# Date : 20191023# Purpose : Generate primes p and q, and write e and n to a public file;# write Phi_n to another file that is private# In this project, I let e=65537'''import randomimport time#Algorithm GCD to compute greatest common divisordef gcd(a,b):while b!=0:y=bb=a%ba=yreturn a#A quickly multiply algorithm with modding ndef Qmul(a,b,n):r=0while b:if b&1:r=(r+a)%nb=b>>1a=(a<<1)%nreturn r#A quidckly exponential algorithm with modding ndef QPow(a,x,n):result=1while x:if x&1:result=(result*a)%nx=x>>1a=(a*a)%nreturn result#Find the number = (n-1)/2^kdef Find_q(n):while not n&1:n=n>>1return n#Miller Rabin algorithmdef Miller_Rabin(a,n):q=Find_q(n-1)aq=QPow(a,q,n)#final condition,q=n-1while q<n:if aq==1 or aq==-1:return True#make aq = aq(q*2^j)aq=QPow(aq,2,n)q=q<<1return False#A quickly algorithm to make a odd numberdef Build_Random_Odd(nbit):#hightest bit = 1number=1#every bit value = 0 or 1while nbit-2:number=(number<<1)|random.randint(0,1)nbit=nbit-1#lowest bit = 1, make it is oddnumber=(number<<1)|1return number#A algorithm to test whether a number is a primedef Judge_Prime(n):#using Miller Rabin to test is in 10 timest=10while t:t-=1a=random.randint(2,n-1)if not Miller_Rabin(a,n):return Falsereturn True#A algrothm to build prime p and q, and gcd(e,Phi(n))=1#because Phi(n)=(p-1)*(q-1), if gcd(e,Phi(n))!=1, e must be the factor or exist a common divisor but not = 1, with p-1 or q-1def Build_Prime(e):while True:i=0p_flag=Falsep_bit=random.randint(512,1024)p=Build_Random_Odd(p_bit)#if it is not a prime, maybe it plus 2 will be#try 100 times, meaning plus 200while i<100:if Judge_Prime(p):p_flag=Truebreakelse:p=p+2i+=1continue#if (p-1) don't coprime e, make another p againif p_flag and gcd(e,p-1)==1:breakelse:continuewhile True:j=0q_flag=Falseq_bit=random.randint(512,1024)q=Build_Random_Odd(q_bit)while j<100:if Judge_Prime(q):q_flag=Truebreakelse:q=q+2j+=1continueif q_flag and gcd(e,q)==1:breakelse:continuereturn p,qstarttime = time.time()e=65537p,q=Build_Prime(e)n=p*qPhi_n=(p-1)*(q-1)#write e and n to a public filefpu=open("publicfile.txt","w+")fpu.write(str(e)+'\n')fpu.write(str(n))fpu.close()#write Phi(n) to a private filefpr=open("privatefile.txt","w+")fpr.write(str(Phi_n))fpr.close()endtime = time.time()#running timeprint(endtime - starttime)
'''# File : SHA3.py# Author : Hongpei Lin# Date : 20191204# Purpose : Hash Function,input data n(any bits), output hash value l(any bits you want)'''import hashlibimport numpy as npimport codecs#Padding Function#Input data bits n and block unit length(n:string type;r:int type),and len(n)%8=0#Output data bits n' that is r|n'(string type)def Padding(n,r):mod=len(n)%rpad_count=r-modif pad_count==8:n=n+"01100001"else:n=n+"011"+"0"*(pad_count-4)+"1"return n#Block Function, block the data n, get blocks of n#Input n:string type,r:int type#output: list type, which value is string typedef Block(n,r):BlockList=[]index=0length_n=len(n)while index<length_n:s=n[index:index+r]news=""si=0while si<r:news+=s[si:si+64][::-1]si=si+64BlockList.append(news)index+=rreturn BlockList#n=1600bit, build a matrix 5*5*64;#in this matrix, I let it be a 25*64 matrix; sign row=index/5;colunm=index%5 in minddef Build_Matrix(n):n_list=[]index=0while index<len(n):n_list.append(n[index:index+64])index+=64return n_list#0 step in f Function#theta function,input 25*64matrix, oupput 25*64, both are string in list.def theta(M):T=["" for i in range(25)]for j in range(64):#all lanes compute in the same timesigma0=[0,0,0,0,0]#sigma(a[(x-1),y',z])sigma1=[0,0,0,0,0]#sigma(a[(x+1),y',(z-1)]for i in range(5):sigma0[i]=int(M[(i-1)%25][j])^int(M[(i-6)%25][j])^int(M[(i-11)%25][j])^int(M[(i-16)%25][j])^int(M[(i-21)%25][j])sigma1[i]=int(M[(i+1)%25][(j+1)%64])^int(M[(i+6)%25][(j+1)%64])^int(M[(i+11)%25][(j+1)%64])^int(M[(i+16)%25][(j+1)%64])^int(M[(i+21)%25][(j+1)%64])for i in range(25):T[i]=T[i]+str(int(M[i][j])^int(sigma0[i%5])^int(sigma1[i%5]))return TT_Table=[0,1,62,28,27,36,44,6,55,20,3,10,43,25,39,41,45,15,21,8,18,2,61,56,14]#1 step in f Function#rho function:shift in every lane#input a 25*64 matrix and T table, output a new matrix 25*64def rho(M,table):for i in range(25):s=M[i]M[i]=s[table[i]:]+s[:table[i]]return M#2 step in f Function#pi function:lane confusion#input a 25*64 matrix and T table, output a new matrix 25*64def pi(M):v_Matrix=np.array([[0, 1], [2, 3]])New_Matrix=[""for i in range(25)]for i in range(25):x,y=i%5,i//5#x=colunm;y=rowInitial_Matrix=np.array([[x],[y]])N_Matrix=v_Matrix.dot(Initial_Matrix)index=int(N_Matrix[0][0]%5+(N_Matrix[1][0]%5)*5)New_Matrix[index]=New_Matrix[index]+M[i]return New_Matrix#3 step in f Function#chi function:bits transformation#input a 25*64 matrix output a new matrix 25*64def chi(M):T=["" for i in range(25)]for j in range(64):for i in range(25):row=i//5x_1,x_2=i+1,i+2#x_1=x+1,x_2=x+2 in a same rowif not x_1<(row+1)*5:x_1=x_1-5if not x_2<(row+1)*5:x_2=x_2-5T[i]=T[i]+str(int(M[i][j])^(int(M[x_1][j])^1)&int(M[x_2][j]))return T#4 step in f function#iota function:transformation of first lane in every round#input a 25*64 matrix and RC and ordinal round, output a new matrix 25*64RC=[1,int('8082',16),int('800000000000808A',16),int('8000000080008000',16),int('808b',16),int('0000000080000001',16),int('8000000080008081',16),int('8000000000008009',16),int('8a',16),int('88',16),int('0000000080008009',16),int('000000008000000A',16),int('000000008000808B',16),int('800000000000008B',16),int('8000000000008089',16),int('8000000000008003',16),int('8000000000008002',16),int('8000000000000080',16),int('000000000000800A',16),int('800000008000000A',16),int('8000000080008081',16),int('8000000000008080',16),int('0000000080000001',16),int('8000000080008008',16)]def iota(M,Rc,i):M[0]=bin(int(M[0],2)^Rc[i])[2:]pad_count=64-len(M[0])#padding, let string len=64zero="0"*pad_countM[0]=zero+M[0]return M#f function, input 1600bits string,output 1600bits stringdef f(s):s_Matrix=Build_Matrix(s)for i in range(24):#24 roundss_Matrix=iota(chi(pi(rho(theta(s_Matrix),T_Table))),RC,i)news=""for i in s_Matrix:news+=ireturn newsdef absorbing(s,r):s=Padding(s,r)#paddingP_list=Block(s,r)#blockc="0"*(1600-r)news="0"*1600#initial sfor i in range(len(P_list)):P_list[i]=P_list[i]+cnews=bin(int(P_list[i],2)^int(news,2))[2:]pad_count=1600-len(news)#padding , let string len=1600zero="0"*pad_countnews=zero+newsnews=f(news)return newsdef squeezing(s,r,l):b=s[:r]i64,i8=0,0templist=[]while i64<len(b):temp_b=b[i64:i64+64]i8state=i8+64while i8state>i8:templist.append(b[i8state-8:i8state])i8state-=8i8+=64i64+=64news=""for i in templist:news+=iif not l>r:return news[:l]BlockCount=l//r+1while BlockCount:b=f(b)templist=[]i64,i8=0,0while i64<len(b):temp_b=b[i64:i64+64]i8state=i8+64while i8state>i8:templist.append(b[i8state-8:i8state])i8state-=8i8+=64i64+=64for i in templist:news+=iBlockCount-=1return news[:l]def HashSHA3(s,l):s=absorbing(s,1600-l-l)s=squeezing(s,1600-l-l,l)s=hex(int(s,2))[2:]while len(s)<l//4:s="0"+sreturn sdef MakeSHA3(filename,l):fr=codecs.open(filename,"r",encoding='utf-8')msg=fr.read()fr.close()msgstream=""for i in msg:temp=bin(ord(i))[2:]while len(temp)%8!=0:temp="0"+tempmsgstream+=temphashvalue=HashSHA3(msgstream,l)fw=codecs.open("HashFile.txt","w",encoding='utf-8')fw.write(hashvalue)fw.close()return True
'''# File : RSA.py# Author : Hongpei Lin# Date : 20191023# Purpose : RSA'''import reimport codecsimport SHA3def egcd(a,b):r0,r1,s0,s1,t=1,0,0,1,bwhile b:q,a,b=a//b,b,a%br0,r1=r1,r0-q*r1s0,s1=s1,s0-q*s1if r0<0:r0=r0%treturn r0def QPow(a,x,n):result=1while x:if x&1:result=(result*a)%nx=x>>1a=(a*a)%nreturn result#Get public key in a public fliedef Get_PuKey(puf):fpu=open(puf,"r")l=[]for line in fpu.readlines():l.append(int(line))fpu.close()e,n=l[0],l[1]return e,n#Get private key in a private filedef Get_PrKey(puf,prf):e,n=Get_PuKey(puf)fpr=open(prf,"r")Phi_n=int(fpr.read())fpr.close()d=egcd(e,Phi_n)return d,n#make a string become bitstreamdef Str_to_Byte(s):news=""for i in s:news=news+"{:08b}".format(ord(i))return news#block the plain, every block has 1024 bits#input a bitstream,output a listdef BlockPlain(n):nlist=[]nlength=len(n)if not nlength>1024:nlist.append(n)return nlisti=0while i>nlength:nlist.append(n[i:i+1024])i+=1024nlist.append(n[i:])return nlist#RSA encrypt and decrypt, accordings using public key or private keydef RSA_Encrypt(s,e,n):news=Str_to_Byte(s)Clist=BlockPlain(news)Cstring=""for i in Clist:value=int(i,2)encryption=QPow(value,e,n)encryption=bin(encryption)[2:]while len(encryption)%8!=0:encryption="0"+encryptionCstring=Cstring+encryptionCrylist=re.findall(r'.{8}',Cstring)s1=""for i in Crylist:s1+=chr(int(i,2))return s1#encrypt plaintextdef EncryptText(puf):PlainTextFile=input("Please input the filename you wanna encrypt\n")fo=codecs.open(PlainTextFile,"r",encoding='utf-8')PlainText=fo.read()fo.close()e,n=Get_PuKey(puf)Encrypttext=RSA_Encrypt(PlainText,e,n)fw=codecs.open("EncryptText.txt","w",encoding='utf-8')fw.write(Encrypttext)fw.close()return True#decryptdef DecryptText(puf,prf):d,n=Get_PrKey(puf,prf)EncryptFile=input("Please input the filename you wanna decrypt\n")fo=codecs.open(EncryptFile,"r",encoding='utf-8')EncryptFileText=fo.read()fo.close()Decrypttext=RSA_Encrypt(EncryptFileText,d,n)fw=codecs.open("DecryptText.txt","w+",encoding='utf-8')fw.write(RSA_Encrypt(EncryptFileText,d,n))fw.close()return True#Digital signatruedef SignaTrue(puf,prf):d,n=Get_PrKey(puf,prf)message=input("Please input the filename of the message!\n")fr=codecs.open(message,"r",encoding='utf-8')Mstring=fr.read()fr.close()msgstream=""for i in Mstring:temp=bin(ord(i))[2:]while len(temp)%8!=0:temp="0"+tempmsgstream+=tempHmessage=SHA3.HashSHA3(msgstream,256)Sign=RSA_Encrypt(Hmessage,d,n)fw=codecs.open("Signatrue.txt","w+",encoding='utf-8')fw.write(Sign)fw.close()return True#Authenticationdef JudgeSign(puf):e,n=Get_PuKey(puf)sign=input("Please input the filename of the signatrue!\n")message=input("Please input the filename of the message!\n")fr=codecs.open(message,"r",encoding='utf-8')Mstring=fr.read()fr.close()msgstream=""for i in Mstring:temp=bin(ord(i))[2:]while len(temp)%8!=0:temp="0"+tempmsgstream+=tempHmessage=SHA3.HashSHA3(msgstream, 256)fs=codecs.open(sign,"r",encoding='utf-8')sign=fs.read()fs.close()Auth=RSA_Encrypt(sign,e,n)if Auth==Hmessage:return Trueelse:return Falsedef __main__():select="Please select the functions\n"encrypt="0:Encrypt\n"decrypt="1:Decrypt\n"Sign="2:Signature\n"Authentication="3:Authentication\n"out="Other:Exit\n"pukeyfile="publicfile.txt"prkeyfile="privatefile.txt"while True:project=input(select+encrypt+decrypt+Sign+Authentication+out)if project=="0":if EncryptText(pukeyfile):print("Encrypt Successfully!")continueelse:print("Encrypt Failed!")continueelif project=="1":if DecryptText(pukeyfile,prkeyfile):print("DecryptText Successfully!")continueelse:print("Encrypt Failed!")continueelif project=="2":if SignaTrue(pukeyfile,prkeyfile):print("Signatrue Successfully!")continueelse:print("Signatrue Failed!")continueelif project=="3":if JudgeSign(pukeyfile):print("Authentication Successfully!")continueelse:print("Authentication Failed!")continueelse:breakif __name__=="__main__":__main__()