python实现的DES加密算法和3DES加密算法实例
本文实例讲述了python实现的DES加密算法和3DES加密算法。分享给大家供大家参考。具体实现方法如下:
############################################################################# #Documentation# ############################################################################# #Author:ToddWhiteman #Date:16thMarch,2009 #Verion:2.0.0 #License:PublicDomain-freetodoasyouwish #Homepage:http://twhiteman.netfirms.com/des.html # #ThisisapurepythonimplementationoftheDESencryptionalgorithm. #It'spurepythontoavoidportabilityissues,sincemostDES #implementationsareprogrammedinC(forperformancereasons). # #TripleDESclassisalsoimplemented,utilisingtheDESbase.TripleDES #iseitherDES-EDE3witha24bytekey,orDES-EDE2witha16bytekey. # #SeetheREADME.txtthatshouldcomewiththispythonmoduleforthe #implementationmethodsused. # #Thanksto: #*DavidBroadwellforideas,commentsandsuggestions. #*MarioWolffforpointingoutanddebuggingsometripledesCBCerrors. #*SantiagoPalladinoforprovidingthePKCS5paddingtechnique. #*ShayaforcorrectingthePAD_PKCS5tripledesCBCerrors. # """ApurepythonimplementationoftheDESandTRIPLEDESencryptionalgorithms. Classinitialization -------------------- pyDes.des(key,[mode],[IV],[pad],[padmode]) pyDes.triple_des(key,[mode],[IV],[pad],[padmode]) key->Bytescontainingtheencryptionkey.8bytesforDES,16or24bytes forTripleDES mode->Optionalargumentforencryptiontype,canbeeither pyDes.ECB(ElectronicCodeBook)orpyDes.CBC(CypherBlockChaining) IV->OptionalInitialValuebytes,mustbesuppliedifusingCBCmode. Lengthmustbe8bytes. pad->Optionalargument,setthepadcharacter(PAD_NORMAL)touseduring allencrypt/decrptoperationsdonewiththisinstance. padmode->Optionalargument,setthepaddingmode(PAD_NORMALorPAD_PKCS5) touseduringallencrypt/decrptoperationsdonewiththisinstance. IrecommendtousePAD_PKCS5padding,asthenyouneverneedtoworryaboutany paddingissues,asthepaddingcanberemovedunambiguouslyupondecrypting datathatwasencryptedusingPAD_PKCS5padmode. Commonmethods -------------- encrypt(data,[pad],[padmode]) decrypt(data,[pad],[padmode]) data->Bytestobeencrypted/decrypted pad->Optionalargument.OnlywhenusingpadmodeofPAD_NORMAL.For encryption,addsthischaracterstotheendofthedatablockwhen dataisnotamultipleof8bytes.Fordecryption,willremovethe trailingcharactersthatmatchthispadcharacterfromthelast8 bytesoftheunencrypteddatablock. padmode->Optionalargument,setthepaddingmode,mustbeoneofPAD_NORMAL orPAD_PKCS5).DefaultstoPAD_NORMAL. Example ------- frompyDesimport* data="Pleaseencryptmydata" k=des("DESCRYPT",CBC,"\0\0\0\0\0\0\0\0",pad=None,padmode=PAD_PKCS5) #ForPython3,you'llneedtousebytes,i.e.: #data=b"Pleaseencryptmydata" #k=des(b"DESCRYPT",CBC,b"\0\0\0\0\0\0\0\0",pad=None,padmode=PAD_PKCS5) d=k.encrypt(data) print"Encrypted:%r"%d print"Decrypted:%r"%k.decrypt(d) assertk.decrypt(d,padmode=PAD_PKCS5)==data Seethemodulesource(pyDes.py)formoreexamplesofuse. YoucanalsorunthepyDes.pyfilewithoutandargumentstoseeasimpletest. Note:Thiscodewasnotwrittenforhigh-endsystemsneedingafast implementation,butratherahandyportablesolutionwithsmallusage. """ importsys #_pythonMajorVersionisusedtohandlePython2andPython3differences. _pythonMajorVersion=sys.version_info[0] #Modesofcrypting/cyphering ECB=0 CBC=1 #Modesofpadding PAD_NORMAL=1 PAD_PKCS5=2 #PAD_PKCS5:isamethodthatwillunambiguouslyremoveallpadding #charactersafterdecryption,whenoriginallyencryptedwith #thispaddingmode. #ForagooddescriptionofthePKCS5paddingtechnique,see: #http://www.faqs.org/rfcs/rfc1423.html #Thebaseclasssharedbydesandtripledes. class_baseDes(object): def__init__(self,mode=ECB,IV=None,pad=None,padmode=PAD_NORMAL): ifIV: IV=self._guardAgainstUnicode(IV) ifpad: pad=self._guardAgainstUnicode(pad) self.block_size=8 #Sanitycheckingofarguments. ifpadandpadmode==PAD_PKCS5: raiseValueError("CannotuseapadcharacterwithPAD_PKCS5") ifIVandlen(IV)!=self.block_size: raiseValueError("InvalidInitialValue(IV),mustbeamultipleof"+str(self.block_size)+"bytes") #Setthepassedinvariables self._mode=mode self._iv=IV self._padding=pad self._padmode=padmode defgetKey(self): """getKey()->bytes""" returnself.__key defsetKey(self,key): """Willsetthecryptingkeyforthisobject.""" key=self._guardAgainstUnicode(key) self.__key=key defgetMode(self): """getMode()->pyDes.ECBorpyDes.CBC""" returnself._mode defsetMode(self,mode): """Setsthetypeofcryptingmode,pyDes.ECBorpyDes.CBC""" self._mode=mode defgetPadding(self): """getPadding()->bytesoflength1.Paddingcharacter.""" returnself._padding defsetPadding(self,pad): """setPadding()->bytesoflength1.Paddingcharacter.""" ifpadisnotNone: pad=self._guardAgainstUnicode(pad) self._padding=pad defgetPadMode(self): """getPadMode()->pyDes.PAD_NORMALorpyDes.PAD_PKCS5""" returnself._padmode defsetPadMode(self,mode): """Setsthetypeofpaddingmode,pyDes.PAD_NORMALorpyDes.PAD_PKCS5""" self._padmode=mode defgetIV(self): """getIV()->bytes""" returnself._iv defsetIV(self,IV): """WillsettheInitialValue,usedinconjunctionwithCBCmode""" ifnotIVorlen(IV)!=self.block_size: raiseValueError("InvalidInitialValue(IV),mustbeamultipleof"+str(self.block_size)+"bytes") IV=self._guardAgainstUnicode(IV) self._iv=IV def_padData(self,data,pad,padmode): #Paddatadependingonthemode ifpadmodeisNone: #Getthedefaultpaddingmode. padmode=self.getPadMode() ifpadandpadmode==PAD_PKCS5: raiseValueError("CannotuseapadcharacterwithPAD_PKCS5") ifpadmode==PAD_NORMAL: iflen(data)%self.block_size==0: #Nopaddingrequired. returndata ifnotpad: #Getthedefaultpadding. pad=self.getPadding() ifnotpad: raiseValueError("Datamustbeamultipleof"+str(self.block_size)+"bytesinlength.Usepadmode=PAD_PKCS5orsetthepadcharacter.") data+=(self.block_size-(len(data)%self.block_size))*pad elifpadmode==PAD_PKCS5: pad_len=8-(len(data)%self.block_size) if_pythonMajorVersion<3: data+=pad_len*chr(pad_len) else: data+=bytes([pad_len]*pad_len) returndata def_unpadData(self,data,pad,padmode): #Unpaddatadependingonthemode. ifnotdata: returndata ifpadandpadmode==PAD_PKCS5: raiseValueError("CannotuseapadcharacterwithPAD_PKCS5") ifpadmodeisNone: #Getthedefaultpaddingmode. padmode=self.getPadMode() ifpadmode==PAD_NORMAL: ifnotpad: #Getthedefaultpadding. pad=self.getPadding() ifpad: data=data[:-self.block_size]+\ data[-self.block_size:].rstrip(pad) elifpadmode==PAD_PKCS5: if_pythonMajorVersion<3: pad_len=ord(data[-1]) else: pad_len=data[-1] data=data[:-pad_len] returndata def_guardAgainstUnicode(self,data): #Onlyacceptbytestringsorasciiunicodevalues,otherwise #thereisnowaytocorrectlydecodethedataintobytes. if_pythonMajorVersion<3: ifisinstance(data,unicode): raiseValueError("pyDescanonlyworkwithbytes,notUnicodestrings.") else: ifisinstance(data,str): #Onlyacceptasciiunicodevalues. try: returndata.encode('ascii') exceptUnicodeEncodeError: pass raiseValueError("pyDescanonlyworkwithencodedstrings,notUnicode.") returndata ############################################################################# #DES# ############################################################################# classdes(_baseDes): """DESencryption/decrytpionclass SupportsECB(ElectronicCodeBook)andCBC(CypherBlockChaining)modes. pyDes.des(key,[mode],[IV]) key->Bytescontainingtheencryptionkey,mustbeexactly8bytes mode->Optionalargumentforencryptiontype,canbeeitherpyDes.ECB (ElectronicCodeBook),pyDes.CBC(CypherBlockChaining) IV->OptionalInitialValuebytes,mustbesuppliedifusingCBCmode. Mustbe8bytesinlength. pad->Optionalargument,setthepadcharacter(PAD_NORMAL)touse duringallencrypt/decrptoperationsdonewiththisinstance. padmode->Optionalargument,setthepaddingmode(PAD_NORMALor PAD_PKCS5)touseduringallencrypt/decrptoperationsdone withthisinstance. """ #PermutationandtranslationtablesforDES __pc1=[56,48,40,32,24,16,8, ,57,49,41,33,25,17, ,1,58,50,42,34,26, ,10,2,59,51,43,35, ,54,46,38,30,22,14, ,61,53,45,37,29,21, ,5,60,52,44,36,28, ,12,4,27,19,11,3 ] #numberleftrotationsofpc1 __left_rotations=[ ,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 ] #permutedchoicekey(table2) __pc2=[ ,16,10,23,0,4, ,27,14,5,20,9, ,18,11,3,25,7, ,6,26,19,12,1, ,51,30,36,46,54, ,39,50,44,32,47, ,48,38,55,33,52, ,41,49,35,28,31 ] #initialpermutationIP __ip=[57,49,41,33,25,17,9,1, ,51,43,35,27,19,11,3, ,53,45,37,29,21,13,5, ,55,47,39,31,23,15,7, ,48,40,32,24,16,8,0, ,50,42,34,26,18,10,2, ,52,44,36,28,20,12,4, ,54,46,38,30,22,14,6 ] #Expansiontableforturning32bitblocksinto48bits __expansion_table=[ ,0,1,2,3,4, ,4,5,6,7,8, ,8,9,10,11,12, ,12,13,14,15,16, ,16,17,18,19,20, ,20,21,22,23,24, ,24,25,26,27,28, ,28,29,30,31,0 ] #The(in)famousS-boxes __sbox=[ #S1 [14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7, ,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8, ,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0, ,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13], #S2 [15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10, ,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5, ,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15, ,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9], #S3 [10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8, ,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1, ,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7, ,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12], #S4 [7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15, ,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9, ,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4, ,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14], #S5 [2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9, ,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6, ,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14, ,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3], #S6 [12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11, ,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8, ,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6, ,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13], #S7 [4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1, ,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6, ,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2, ,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12], #S8 [13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7, ,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2, ,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8, ,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11], ] #32-bitpermutationfunctionPusedontheoutputoftheS-boxes __p=[ ,6,19,20,28,11, ,16,0,14,22,25, ,17,30,9,1,7, ,13,31,26,2,8, ,12,29,5,21,10, ,24 ] #finalpermutationIP^-1 __fp=[ ,7,47,15,55,23,63,31, ,6,46,14,54,22,62,30, ,5,45,13,53,21,61,29, ,4,44,12,52,20,60,28, ,3,43,11,51,19,59,27, ,2,42,10,50,18,58,26, ,1,41,9,49,17,57,25, ,0,40,8,48,16,56,24 ] #Typeofcryptingbeingdone ENCRYPT=0x00 DECRYPT=0x01 #Initialisation def__init__(self,key,mode=ECB,IV=None,pad=None,padmode=PAD_NORMAL): #Sanitycheckingofarguments. iflen(key)!=8: raiseValueError("InvalidDESkeysize.Keymustbeexactly8byteslong.") _baseDes.__init__(self,mode,IV,pad,padmode) self.key_size=8 self.L=[] self.R=[] self.Kn=[[0]*48]*16#1648-bitkeys(K1-K16) self.final=[] self.setKey(key) defsetKey(self,key): """Willsetthecryptingkeyforthisobject.Mustbe8bytes.""" _baseDes.setKey(self,key) self.__create_sub_keys() def__String_to_BitList(self,data): """Turnthestringdata,intoalistofbits(1,0)'s""" if_pythonMajorVersion<3: #Turnthestringsintointegers.Python3usesabytes #class,whichalreadyhasthisbehaviour. data=[ord(c)forcindata] l=len(data)*8 result=[0]*l pos=0 forchindata: i=7 whilei>=0: ifch&(1<<i)!=0: result[pos]=1 else: result[pos]=0 pos+=1 i-=1 returnresult def__BitList_to_String(self,data): """Turnthelistofbits->data,intoastring""" result=[] pos=0 c=0 whilepos<len(data): c+=data[pos]<<(7-(pos%8)) if(pos%8)==7: result.append(c) c=0 pos+=1 if_pythonMajorVersion<3: return''.join([chr(c)forcinresult]) else: returnbytes(result) def__permutate(self,table,block): """Permutatethisblockwiththespecifiedtable""" returnlist(map(lambdax:block[x],table)) #Transformthesecretkey,sothatitisreadyfordataprocessing #Createthe16subkeys,K[1]-K[16] def__create_sub_keys(self): """Createthe16subkeysK[1]toK[16]fromthegivenkey""" key=self.__permutate(des.__pc1,self.__String_to_BitList(self.getKey())) i=0 #SplitintoLeftandRightsections self.L=key[:28] self.R=key[28:] whilei<16: j=0 #Performcircularleftshifts whilej<des.__left_rotations[i]: self.L.append(self.L[0]) delself.L[0] self.R.append(self.R[0]) delself.R[0] j+=1 #Createoneofthe16subkeysthroughpc2permutation self.Kn[i]=self.__permutate(des.__pc2,self.L+self.R) i+=1 #Mainpartoftheencryptionalgorithm,thenumbercruncher:) def__des_crypt(self,block,crypt_type): """CrypttheblockofdatathroughDESbit-manipulation""" block=self.__permutate(des.__ip,block) self.L=block[:32] self.R=block[32:] #EncryptionstartsfromKn[1]throughtoKn[16] ifcrypt_type==des.ENCRYPT: iteration=0 iteration_adjustment=1 #DecryptionstartsfromKn[16]downtoKn[1] else: iteration=15 iteration_adjustment=-1 i=0 whilei<16: #MakeacopyofR[i-1],thiswilllaterbecomeL[i] tempR=self.R[:] #PermutateR[i-1]tostartcreatingR[i] self.R=self.__permutate(des.__expansion_table,self.R) #ExclusiveorR[i-1]withK[i],createB[1]toB[8]whilsthere self.R=list(map(lambdax,y:x^y,self.R,self.Kn[iteration])) B=[self.R[:6],self.R[6:12],self.R[12:18],self.R[18:24],self.R[24:30],self.R[30:36],self.R[36:42],self.R[42:]] #Optimization:Replacedbelowcommentedcodewithabove #j=0 #B=[] #whilej<len(self.R): #self.R[j]=self.R[j]^self.Kn[iteration][j] #j+=1 #ifj%6==0: #B.append(self.R[j-6:j]) #PermutateB[1]toB[8]usingtheS-Boxes j=0 Bn=[0]*32 pos=0 whilej<8: #Workouttheoffsets m=(B[j][0]<<1)+B[j][5] n=(B[j][1]<<3)+(B[j][2]<<2)+(B[j][3]<<1)+B[j][4] #Findthepermutationvalue v=des.__sbox[j][(m<<4)+n] #Turnvalueintobits,addittoresult:Bn Bn[pos]=(v&8)>>3 Bn[pos+1]=(v&4)>>2 Bn[pos+2]=(v&2)>>1 Bn[pos+3]=v&1 pos+=4 j+=1 #PermutatetheconcatinationofB[1]toB[8](Bn) self.R=self.__permutate(des.__p,Bn) #XorwithL[i-1] self.R=list(map(lambdax,y:x^y,self.R,self.L)) #Optimization:Thisnowreplacesthebelowcommentedcode #j=0 #whilej<len(self.R): #self.R[j]=self.R[j]^self.L[j] #j+=1 #L[i]becomesR[i-1] self.L=tempR i+=1 iteration+=iteration_adjustment #FinalpermutationofR[16]L[16] self.final=self.__permutate(des.__fp,self.R+self.L) returnself.final #Datatobeencrypted/decrypted defcrypt(self,data,crypt_type): """Cryptthedatainblocks,runningitthroughdes_crypt()""" #Errorcheckthedata ifnotdata: return'' iflen(data)%self.block_size!=0: ifcrypt_type==des.DECRYPT:#Decryptionmustworkon8byteblocks raiseValueError("Invaliddatalength,datamustbeamultipleof"+str(self.block_size)+"bytes\n.") ifnotself.getPadding(): raiseValueError("Invaliddatalength,datamustbeamultipleof"+str(self.block_size)+"bytes\n.Trysettingtheoptionalpaddingcharacter") else: data+=(self.block_size-(len(data)%self.block_size))*self.getPadding() #print"Lenofdata:%f"%(len(data)/self.block_size) ifself.getMode()==CBC: ifself.getIV(): iv=self.__String_to_BitList(self.getIV()) else: raiseValueError("ForCBCmode,youmustsupplytheInitialValue(IV)forciphering") #Splitthedataintoblocks,cryptingeachoneseperately i=0 dict={} result=[] #cached=0 #lines=0 whilei<len(data): #Testcodeforcachingencryptionresults #lines+=1 #ifdict.has_key(data[i:i+8]): #print"Cachedresultfor:%s"%data[i:i+8] #cached+=1 #result.append(dict[data[i:i+8]]) #i+=8 #continue block=self.__String_to_BitList(data[i:i+8]) #XorwithIVifusingCBCmode ifself.getMode()==CBC: ifcrypt_type==des.ENCRYPT: block=list(map(lambdax,y:x^y,block,iv)) #j=0 #whilej<len(block): #block[j]=block[j]^iv[j] #j+=1 processed_block=self.__des_crypt(block,crypt_type) ifcrypt_type==des.DECRYPT: processed_block=list(map(lambdax,y:x^y,processed_block,iv)) #j=0 #whilej<len(processed_block): #processed_block[j]=processed_block[j]^iv[j] #j+=1 iv=block else: iv=processed_block else: processed_block=self.__des_crypt(block,crypt_type) #Addtheresultingcryptedblocktoourlist #d=self.__BitList_to_String(processed_block) #result.append(d) result.append(self.__BitList_to_String(processed_block)) #dict[data[i:i+8]]=d i+=8 #print"Lines:%d,cached:%d"%(lines,cached) #Returnthefullcryptedstring if_pythonMajorVersion<3: return''.join(result) else: returnbytes.fromhex('').join(result) defencrypt(self,data,pad=None,padmode=None): """encrypt(data,[pad],[padmode])->bytes data:Bytestobeencrypted pad:Optionalargumentforencryptionpadding.Mustonlybeonebyte padmode:Optionalargumentforoverridingthepaddingmode. Thedatamustbeamultipleof8bytesandwillbeencrypted withthealreadyspecifiedkey.Datadoesnothavetobea multipleof8bytesifthepaddingcharacterissupplied,or thepadmodeissettoPAD_PKCS5,asbyteswillthenaddedto ensurethebepaddeddataisamultipleof8bytes. """ data=self._guardAgainstUnicode(data) ifpadisnotNone: pad=self._guardAgainstUnicode(pad) data=self._padData(data,pad,padmode) returnself.crypt(data,des.ENCRYPT) defdecrypt(self,data,pad=None,padmode=None): """decrypt(data,[pad],[padmode])->bytes data:Bytestobeencrypted pad:Optionalargumentfordecryptionpadding.Mustonlybeonebyte padmode:Optionalargumentforoverridingthepaddingmode. Thedatamustbeamultipleof8bytesandwillbedecrypted withthealreadyspecifiedkey.InPAD_NORMALmode,ifthe optionalpaddingcharacterissupplied,thentheun-encrypted datawillhavethepaddingcharactersremovedfromtheendof thebytes.Thispadremovalonlyoccursonthelast8bytesof thedata(lastdatablock).InPAD_PKCS5mode,thespecial paddingendmarkerswillberemovedfromthedataafterdecrypting. """ data=self._guardAgainstUnicode(data) ifpadisnotNone: pad=self._guardAgainstUnicode(pad) data=self.crypt(data,des.DECRYPT) returnself._unpadData(data,pad,padmode) ############################################################################# #TripleDES# ############################################################################# classtriple_des(_baseDes): """TripleDESencryption/decrytpionclass ThisalgorithmusestheDES-EDE3(whena24bytekeyissupplied)or theDES-EDE2(whena16bytekeyissupplied)encryptionmethods. SupportsECB(ElectronicCodeBook)andCBC(CypherBlockChaining)modes. pyDes.des(key,[mode],[IV]) key->Bytescontainingtheencryptionkey,mustbeeither16or byteslong mode->Optionalargumentforencryptiontype,canbeeitherpyDes.ECB (ElectronicCodeBook),pyDes.CBC(CypherBlockChaining) IV->OptionalInitialValuebytes,mustbesuppliedifusingCBCmode. Mustbe8bytesinlength. pad->Optionalargument,setthepadcharacter(PAD_NORMAL)touse duringallencrypt/decrptoperationsdonewiththisinstance. padmode->Optionalargument,setthepaddingmode(PAD_NORMALor PAD_PKCS5)touseduringallencrypt/decrptoperationsdone withthisinstance. """ def__init__(self,key,mode=ECB,IV=None,pad=None,padmode=PAD_NORMAL): _baseDes.__init__(self,mode,IV,pad,padmode) self.setKey(key) defsetKey(self,key): """Willsetthecryptingkeyforthisobject.Either16or24byteslong.""" self.key_size=24#UseDES-EDE3mode iflen(key)!=self.key_size: iflen(key)==16:#UseDES-EDE2mode self.key_size=16 else: raiseValueError("InvalidtripleDESkeysize.Keymustbeeither16or24byteslong") ifself.getMode()==CBC: ifnotself.getIV(): #Usethefirst8bytesofthekey self._iv=key[:self.block_size] iflen(self.getIV())!=self.block_size: raiseValueError("InvalidIV,mustbe8bytesinlength") self.__key1=des(key[:8],self._mode,self._iv, self._padding,self._padmode) self.__key2=des(key[8:16],self._mode,self._iv, self._padding,self._padmode) ifself.key_size==16: self.__key3=self.__key1 else: self.__key3=des(key[16:],self._mode,self._iv, self._padding,self._padmode) _baseDes.setKey(self,key) #Overridesettermethodstoworkonall3keys. defsetMode(self,mode): """Setsthetypeofcryptingmode,pyDes.ECBorpyDes.CBC""" _baseDes.setMode(self,mode) forkeyin(self.__key1,self.__key2,self.__key3): key.setMode(mode) defsetPadding(self,pad): """setPadding()->bytesoflength1.Paddingcharacter.""" _baseDes.setPadding(self,pad) forkeyin(self.__key1,self.__key2,self.__key3): key.setPadding(pad) defsetPadMode(self,mode): """Setsthetypeofpaddingmode,pyDes.PAD_NORMALorpyDes.PAD_PKCS5""" _baseDes.setPadMode(self,mode) forkeyin(self.__key1,self.__key2,self.__key3): key.setPadMode(mode) defsetIV(self,IV): """WillsettheInitialValue,usedinconjunctionwithCBCmode""" _baseDes.setIV(self,IV) forkeyin(self.__key1,self.__key2,self.__key3): key.setIV(IV) defencrypt(self,data,pad=None,padmode=None): """encrypt(data,[pad],[padmode])->bytes data:bytestobeencrypted pad:Optionalargumentforencryptionpadding.Mustonlybeonebyte padmode:Optionalargumentforoverridingthepaddingmode. Thedatamustbeamultipleof8bytesandwillbeencrypted withthealreadyspecifiedkey.Datadoesnothavetobea multipleof8bytesifthepaddingcharacterissupplied,or thepadmodeissettoPAD_PKCS5,asbyteswillthenaddedto ensurethebepaddeddataisamultipleof8bytes. """ ENCRYPT=des.ENCRYPT DECRYPT=des.DECRYPT data=self._guardAgainstUnicode(data) ifpadisnotNone: pad=self._guardAgainstUnicode(pad) #Padthedataaccordingly. data=self._padData(data,pad,padmode) ifself.getMode()==CBC: self.__key1.setIV(self.getIV()) self.__key2.setIV(self.getIV()) self.__key3.setIV(self.getIV()) i=0 result=[] whilei<len(data): block=self.__key1.crypt(data[i:i+8],ENCRYPT) block=self.__key2.crypt(block,DECRYPT) block=self.__key3.crypt(block,ENCRYPT) self.__key1.setIV(block) self.__key2.setIV(block) self.__key3.setIV(block) result.append(block) i+=8 if_pythonMajorVersion<3: return''.join(result) else: returnbytes.fromhex('').join(result) else: data=self.__key1.crypt(data,ENCRYPT) data=self.__key2.crypt(data,DECRYPT) returnself.__key3.crypt(data,ENCRYPT) defdecrypt(self,data,pad=None,padmode=None): """decrypt(data,[pad],[padmode])->bytes data:bytestobeencrypted pad:Optionalargumentfordecryptionpadding.Mustonlybeonebyte padmode:Optionalargumentforoverridingthepaddingmode. Thedatamustbeamultipleof8bytesandwillbedecrypted withthealreadyspecifiedkey.InPAD_NORMALmode,ifthe optionalpaddingcharacterissupplied,thentheun-encrypted datawillhavethepaddingcharactersremovedfromtheendof thebytes.Thispadremovalonlyoccursonthelast8bytesof thedata(lastdatablock).InPAD_PKCS5mode,thespecial paddingendmarkerswillberemovedfromthedataafter decrypting,nopadcharacterisrequiredforPAD_PKCS5. """ ENCRYPT=des.ENCRYPT DECRYPT=des.DECRYPT data=self._guardAgainstUnicode(data) ifpadisnotNone: pad=self._guardAgainstUnicode(pad) ifself.getMode()==CBC: self.__key1.setIV(self.getIV()) self.__key2.setIV(self.getIV()) self.__key3.setIV(self.getIV()) i=0 result=[] whilei<len(data): iv=data[i:i+8] block=self.__key3.crypt(iv,DECRYPT) block=self.__key2.crypt(block,ENCRYPT) block=self.__key1.crypt(block,DECRYPT) self.__key1.setIV(iv) self.__key2.setIV(iv) self.__key3.setIV(iv) result.append(block) i+=8 if_pythonMajorVersion<3: data=''.join(result) else: data=bytes.fromhex('').join(result) else: data=self.__key3.crypt(data,DECRYPT) data=self.__key2.crypt(data,ENCRYPT) data=self.__key1.crypt(data,DECRYPT) returnself._unpadData(data,pad,padmode)
希望本文所述对大家的Python程序设计有所帮助。