您好,欢迎访问一九零五行业门户网

python实现的DES加密算法和3DES加密算法实例

本文实例讲述了python实现的des加密算法和3des加密算法。分享给大家供大家参考。具体实现方法如下:
############################################################################# # documentation # ############################################################################# # author: todd whiteman # date: 16th march, 2009 # verion: 2.0.0 # license: public domain - free to do as you wish # homepage: http://twhiteman.netfirms.com/des.html # # this is a pure python implementation of the des encryption algorithm. # it's pure python to avoid portability issues, since most des # implementations are programmed in c (for performance reasons). # # triple des class is also implemented, utilising the des base. triple des # is either des-ede3 with a 24 byte key, or des-ede2 with a 16 byte key. # # see the readme.txt that should come with this python module for the # implementation methods used. # # thanks to: # * david broadwell for ideas, comments and suggestions. # * mario wolff for pointing out and debugging some triple des cbc errors. # * santiago palladino for providing the pkcs5 padding technique. # * shaya for correcting the pad_pkcs5 triple des cbc errors. # """a pure python implementation of the des and triple des encryption algorithms. class initialization -------------------- pydes.des(key, [mode], [iv], [pad], [padmode]) pydes.triple_des(key, [mode], [iv], [pad], [padmode]) key -> bytes containing the encryption key. 8 bytes for des, 16 or 24 bytes for triple des mode -> optional argument for encryption type, can be either pydes.ecb (electronic code book) or pydes.cbc (cypher block chaining) iv -> optional initial value bytes, must be supplied if using cbc mode. length must be 8 bytes. pad -> optional argument, set the pad character (pad_normal) to use during all encrypt/decrpt operations done with this instance. padmode -> optional argument, set the padding mode (pad_normal or pad_pkcs5) to use during all encrypt/decrpt operations done with this instance. i recommend to use pad_pkcs5 padding, as then you never need to worry about any padding issues, as the padding can be removed unambiguously upon decrypting data that was encrypted using pad_pkcs5 padmode. common methods -------------- encrypt(data, [pad], [padmode]) decrypt(data, [pad], [padmode]) data -> bytes to be encrypted/decrypted pad -> optional argument. only when using padmode of pad_normal. for encryption, adds this characters to the end of the data block when data is not a multiple of 8 bytes. for decryption, will remove the trailing characters that match this pad character from the last 8 bytes of the unencrypted data block. padmode -> optional argument, set the padding mode, must be one of pad_normal or pad_pkcs5). defaults to pad_normal. example ------- from pydes import * data = "please encrypt my data" k = des("descrypt", cbc, "\0\0\0\0\0\0\0\0", pad=none, padmode=pad_pkcs5) # for python3, you'll need to use bytes, i.e.: # data = b"please encrypt my data" # 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) assert k.decrypt(d, padmode=pad_pkcs5) == data see the module source (pydes.py) for more examples of use. you can also run the pydes.py file without and arguments to see a simple test. note: this code was not written for high-end systems needing a fast implementation, but rather a handy portable solution with small usage. """ import sys # _pythonmajorversion is used to handle python2 and python3 differences. _pythonmajorversion = sys.version_info[0] # modes of crypting / cyphering ecb = 0 cbc = 1 # modes of padding pad_normal = 1 pad_pkcs5 = 2 # pad_pkcs5: is a method that will unambiguously remove all padding # characters after decryption, when originally encrypted with # this padding mode. # for a good description of the pkcs5 padding technique, see: # http://www.faqs.org/rfcs/rfc1423.html # the base class shared by des and triple des. class _basedes(object): def __init__(self, mode=ecb, iv=none, pad=none, padmode=pad_normal): if iv: iv = self._guardagainstunicode(iv) if pad: pad = self._guardagainstunicode(pad) self.block_size = 8 # sanity checking of arguments. if pad and padmode == pad_pkcs5: raise valueerror("cannot use a pad character with pad_pkcs5") if iv and len(iv) != self.block_size: raise valueerror("invalid initial value (iv), must be a multiple of " + str(self.block_size) + " bytes") # set the passed in variables self._mode = mode self._iv = iv self._padding = pad self._padmode = padmode def getkey(self): """getkey() -> bytes""" return self.__key def setkey(self, key): """will set the crypting key for this object.""" key = self._guardagainstunicode(key) self.__key = key def getmode(self): """getmode() -> pydes.ecb or pydes.cbc""" return self._mode def setmode(self, mode): """sets the type of crypting mode, pydes.ecb or pydes.cbc""" self._mode = mode def getpadding(self): """getpadding() -> bytes of length 1. padding character.""" return self._padding def setpadding(self, pad): """setpadding() -> bytes of length 1. padding character.""" if pad is not none: pad = self._guardagainstunicode(pad) self._padding = pad def getpadmode(self): """getpadmode() -> pydes.pad_normal or pydes.pad_pkcs5""" return self._padmode def setpadmode(self, mode): """sets the type of padding mode, pydes.pad_normal or pydes.pad_pkcs5""" self._padmode = mode def getiv(self): """getiv() -> bytes""" return self._iv def setiv(self, iv): """will set the initial value, used in conjunction with cbc mode""" if not iv or len(iv) != self.block_size: raise valueerror("invalid initial value (iv), must be a multiple of " + str(self.block_size) + " bytes") iv = self._guardagainstunicode(iv) self._iv = iv def _paddata(self, data, pad, padmode): # pad data depending on the mode if padmode is none: # get the default padding mode. padmode = self.getpadmode() if pad and padmode == pad_pkcs5: raise valueerror("cannot use a pad character with pad_pkcs5") if padmode == pad_normal: if len(data) % self.block_size == 0: # no padding required. return data if not pad: # get the default padding. pad = self.getpadding() if not pad: raise valueerror("data must be a multiple of " + str(self.block_size) + " bytes in length. use padmode=pad_pkcs5 or set the pad character.") data += (self.block_size - (len(data) % self.block_size)) * pad elif padmode == 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) return data def _unpaddata(self, data, pad, padmode): # unpad data depending on the mode. if not data: return data if pad and padmode == pad_pkcs5: raise valueerror("cannot use a pad character with pad_pkcs5") if padmode is none: # get the default padding mode. padmode = self.getpadmode() if padmode == pad_normal: if not pad: # get the default padding. pad = self.getpadding() if pad: data = data[:-self.block_size] + \ data[-self.block_size:].rstrip(pad) elif padmode == pad_pkcs5: if _pythonmajorversion < 3: pad_len = ord(data[-1]) else: pad_len = data[-1] data = data[:-pad_len] return data def _guardagainstunicode(self, data): # only accept byte strings or ascii unicode values, otherwise # there is no way to correctly decode the data into bytes. if _pythonmajorversion < 3: if isinstance(data, unicode): raise valueerror("pydes can only work with bytes, not unicode strings.") else: if isinstance(data, str): # only accept ascii unicode values. try: return data.encode('ascii') except unicodeencodeerror: pass raise valueerror("pydes can only work with encoded strings, not unicode.") return data ############################################################################# # des # ############################################################################# class des(_basedes): """des encryption/decrytpion class supports ecb (electronic code book) and cbc (cypher block chaining) modes. pydes.des(key,[mode], [iv]) key -> bytes containing the encryption key, must be exactly 8 bytes mode -> optional argument for encryption type, can be either pydes.ecb (electronic code book), pydes.cbc (cypher block chaining) iv -> optional initial value bytes, must be supplied if using cbc mode. must be 8 bytes in length. pad -> optional argument, set the pad character (pad_normal) to use during all encrypt/decrpt operations done with this instance. padmode -> optional argument, set the padding mode (pad_normal or pad_pkcs5) to use during all encrypt/decrpt operations done with this instance. """ # permutation and translation tables for des __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 ] # number left rotations of pc1 __left_rotations = [ , 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 ] # permuted choice key (table 2) __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 ] # initial permutation ip __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 ] # expansion table for turning 32 bit blocks into 48 bits __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)famous s-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-bit permutation function p used on the output of the s-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 ] # final permutation ip^-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 ] # type of crypting being done encrypt = 0x00 decrypt = 0x01 # initialisation def __init__(self, key, mode=ecb, iv=none, pad=none, padmode=pad_normal): # sanity checking of arguments. if len(key) != 8: raise valueerror("invalid des key size. key must be exactly 8 bytes long.") _basedes.__init__(self, mode, iv, pad, padmode) self.key_size = 8 self.l = [] self.r = [] self.kn = [ [0] * 48 ] * 16 # 16 48-bit keys (k1 - k16) self.final = [] self.setkey(key) def setkey(self, key): """will set the crypting key for this object. must be 8 bytes.""" _basedes.setkey(self, key) self.__create_sub_keys() def __string_to_bitlist(self, data): """turn the string data, into a list of bits (1, 0)'s""" if _pythonmajorversion < 3: # turn the strings into integers. python 3 uses a bytes # class, which already has this behaviour. data = [ord(c) for c in data] l = len(data) * 8 result = [0] * l pos = 0 for ch in data: i = 7 while i >= 0: if ch & (1 << i) != 0: result[pos] = 1 else: result[pos] = 0 pos += 1 i -= 1 return result def __bitlist_to_string(self, data): """turn the list of bits -> data, into a string""" result = [] pos = 0 c = 0 while pos < 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) for c in result ]) else: return bytes(result) def __permutate(self, table, block): """permutate this block with the specified table""" return list(map(lambda x: block[x], table)) # transform the secret key, so that it is ready for data processing # create the 16 subkeys, k[1] - k[16] def __create_sub_keys(self): """create the 16 subkeys k[1] to k[16] from the given key""" key = self.__permutate(des.__pc1, self.__string_to_bitlist(self.getkey())) i = 0 # split into left and right sections self.l = key[:28] self.r = key[28:] while i < 16: j = 0 # perform circular left shifts while j < des.__left_rotations[i]: self.l.append(self.l[0]) del self.l[0] self.r.append(self.r[0]) del self.r[0] j += 1 # create one of the 16 subkeys through pc2 permutation self.kn[i] = self.__permutate(des.__pc2, self.l + self.r) i += 1 # main part of the encryption algorithm, the number cruncher :) def __des_crypt(self, block, crypt_type): """crypt the block of data through des bit-manipulation""" block = self.__permutate(des.__ip, block) self.l = block[:32] self.r = block[32:] # encryption starts from kn[1] through to kn[16] if crypt_type == des.encrypt: iteration = 0 iteration_adjustment = 1 # decryption starts from kn[16] down to kn[1] else: iteration = 15 iteration_adjustment = -1 i = 0 while i < 16: # make a copy of r[i-1], this will later become l[i] tempr = self.r[:] # permutate r[i - 1] to start creating r[i] self.r = self.__permutate(des.__expansion_table, self.r) # exclusive or r[i - 1] with k[i], create b[1] to b[8] whilst here self.r = list(map(lambda x, 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: replaced below commented code with above #j = 0 #b = [] #while j < len(self.r): # self.r[j] = self.r[j] ^ self.kn[iteration][j] # j += 1 # if j % 6 == 0: # b.append(self.r[j-6:j]) # permutate b[1] to b[8] using the s-boxes j = 0 bn = [0] * 32 pos = 0 while j < 8: # work out the offsets m = (b[j][0] << 1) + b[j][5] n = (b[j][1] << 3) + (b[j][2] << 2) + (b[j][3] << 1) + b[j][4] # find the permutation value v = des.__sbox[j][(m << 4) + n] # turn value into bits, add it to result: 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 # permutate the concatination of b[1] to b[8] (bn) self.r = self.__permutate(des.__p, bn) # xor with l[i - 1] self.r = list(map(lambda x, y: x ^ y, self.r, self.l)) # optimization: this now replaces the below commented code #j = 0 #while j < len(self.r): # self.r[j] = self.r[j] ^ self.l[j] # j += 1 # l[i] becomes r[i - 1] self.l = tempr i += 1 iteration += iteration_adjustment # final permutation of r[16]l[16] self.final = self.__permutate(des.__fp, self.r + self.l) return self.final # data to be encrypted/decrypted def crypt(self, data, crypt_type): """crypt the data in blocks, running it through des_crypt()""" # error check the data if not data: return '' if len(data) % self.block_size != 0: if crypt_type == des.decrypt: # decryption must work on 8 byte blocks raise valueerror("invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n.") if not self.getpadding(): raise valueerror("invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n. try setting the optional padding character") else: data += (self.block_size - (len(data) % self.block_size)) * self.getpadding() # print "len of data: %f" % (len(data) / self.block_size) if self.getmode() == cbc: if self.getiv(): iv = self.__string_to_bitlist(self.getiv()) else: raise valueerror("for cbc mode, you must supply the initial value (iv) for ciphering") # split the data into blocks, crypting each one seperately i = 0 dict = {} result = [] #cached = 0 #lines = 0 while i < len(data): # test code for caching encryption results #lines += 1 #if dict.has_key(data[i:i+8]): #print "cached result for: %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]) # xor with iv if using cbc mode if self.getmode() == cbc: if crypt_type == des.encrypt: block = list(map(lambda x, y: x ^ y, block, iv)) #j = 0 #while j < len(block): # block[j] = block[j] ^ iv[j] # j += 1 processed_block = self.__des_crypt(block, crypt_type) if crypt_type == des.decrypt: processed_block = list(map(lambda x, y: x ^ y, processed_block, iv)) #j = 0 #while j < 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) # add the resulting crypted block to our list #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) # return the full crypted string if _pythonmajorversion < 3: return ''.join(result) else: return bytes.fromhex('').join(result) def encrypt(self, data, pad=none, padmode=none): """encrypt(data, [pad], [padmode]) -> bytes data : bytes to be encrypted pad : optional argument for encryption padding. must only be one byte padmode : optional argument for overriding the padding mode. the data must be a multiple of 8 bytes and will be encrypted with the already specified key. data does not have to be a multiple of 8 bytes if the padding character is supplied, or the padmode is set to pad_pkcs5, as bytes will then added to ensure the be padded data is a multiple of 8 bytes. """ data = self._guardagainstunicode(data) if pad is not none: pad = self._guardagainstunicode(pad) data = self._paddata(data, pad, padmode) return self.crypt(data, des.encrypt) def decrypt(self, data, pad=none, padmode=none): """decrypt(data, [pad], [padmode]) -> bytes data : bytes to be encrypted pad : optional argument for decryption padding. must only be one byte padmode : optional argument for overriding the padding mode. the data must be a multiple of 8 bytes and will be decrypted with the already specified key. in pad_normal mode, if the optional padding character is supplied, then the un-encrypted data will have the padding characters removed from the end of the bytes. this pad removal only occurs on the last 8 bytes of the data (last data block). in pad_pkcs5 mode, the special padding end markers will be removed from the data after decrypting. """ data = self._guardagainstunicode(data) if pad is not none: pad = self._guardagainstunicode(pad) data = self.crypt(data, des.decrypt) return self._unpaddata(data, pad, padmode) ############################################################################# # triple des # ############################################################################# class triple_des(_basedes): """triple des encryption/decrytpion class this algorithm uses the des-ede3 (when a 24 byte key is supplied) or the des-ede2 (when a 16 byte key is supplied) encryption methods. supports ecb (electronic code book) and cbc (cypher block chaining) modes. pydes.des(key, [mode], [iv]) key -> bytes containing the encryption key, must be either 16 or bytes long mode -> optional argument for encryption type, can be either pydes.ecb (electronic code book), pydes.cbc (cypher block chaining) iv -> optional initial value bytes, must be supplied if using cbc mode. must be 8 bytes in length. pad -> optional argument, set the pad character (pad_normal) to use during all encrypt/decrpt operations done with this instance. padmode -> optional argument, set the padding mode (pad_normal or pad_pkcs5) to use during all encrypt/decrpt operations done with this instance. """ def __init__(self, key, mode=ecb, iv=none, pad=none, padmode=pad_normal): _basedes.__init__(self, mode, iv, pad, padmode) self.setkey(key) def setkey(self, key): """will set the crypting key for this object. either 16 or 24 bytes long.""" self.key_size = 24 # use des-ede3 mode if len(key) != self.key_size: if len(key) == 16: # use des-ede2 mode self.key_size = 16 else: raise valueerror("invalid triple des key size. key must be either 16 or 24 bytes long") if self.getmode() == cbc: if not self.getiv(): # use the first 8 bytes of the key self._iv = key[:self.block_size] if len(self.getiv()) != self.block_size: raise valueerror("invalid iv, must be 8 bytes in length") 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) if self.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) # override setter methods to work on all 3 keys. def setmode(self, mode): """sets the type of crypting mode, pydes.ecb or pydes.cbc""" _basedes.setmode(self, mode) for key in (self.__key1, self.__key2, self.__key3): key.setmode(mode) def setpadding(self, pad): """setpadding() -> bytes of length 1. padding character.""" _basedes.setpadding(self, pad) for key in (self.__key1, self.__key2, self.__key3): key.setpadding(pad) def setpadmode(self, mode): """sets the type of padding mode, pydes.pad_normal or pydes.pad_pkcs5""" _basedes.setpadmode(self, mode) for key in (self.__key1, self.__key2, self.__key3): key.setpadmode(mode) def setiv(self, iv): """will set the initial value, used in conjunction with cbc mode""" _basedes.setiv(self, iv) for key in (self.__key1, self.__key2, self.__key3): key.setiv(iv) def encrypt(self, data, pad=none, padmode=none): """encrypt(data, [pad], [padmode]) -> bytes data : bytes to be encrypted pad : optional argument for encryption padding. must only be one byte padmode : optional argument for overriding the padding mode. the data must be a multiple of 8 bytes and will be encrypted with the already specified key. data does not have to be a multiple of 8 bytes if the padding character is supplied, or the padmode is set to pad_pkcs5, as bytes will then added to ensure the be padded data is a multiple of 8 bytes. """ encrypt = des.encrypt decrypt = des.decrypt data = self._guardagainstunicode(data) if pad is not none: pad = self._guardagainstunicode(pad) # pad the data accordingly. data = self._paddata(data, pad, padmode) if self.getmode() == cbc: self.__key1.setiv(self.getiv()) self.__key2.setiv(self.getiv()) self.__key3.setiv(self.getiv()) i = 0 result = [] while i < 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: return bytes.fromhex('').join(result) else: data = self.__key1.crypt(data, encrypt) data = self.__key2.crypt(data, decrypt) return self.__key3.crypt(data, encrypt) def decrypt(self, data, pad=none, padmode=none): """decrypt(data, [pad], [padmode]) -> bytes data : bytes to be encrypted pad : optional argument for decryption padding. must only be one byte padmode : optional argument for overriding the padding mode. the data must be a multiple of 8 bytes and will be decrypted with the already specified key. in pad_normal mode, if the optional padding character is supplied, then the un-encrypted data will have the padding characters removed from the end of the bytes. this pad removal only occurs on the last 8 bytes of the data (last data block). in pad_pkcs5 mode, the special padding end markers will be removed from the data after decrypting, no pad character is required for pad_pkcs5. """ encrypt = des.encrypt decrypt = des.decrypt data = self._guardagainstunicode(data) if pad is not none: pad = self._guardagainstunicode(pad) if self.getmode() == cbc: self.__key1.setiv(self.getiv()) self.__key2.setiv(self.getiv()) self.__key3.setiv(self.getiv()) i = 0 result = [] while i < 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) return self._unpaddata(data, pad, padmode)
希望本文所述对大家的python程序设计有所帮助。
其它类似信息

推荐信息