⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pydes.py

📁 A pure python module which implements the DES and Triple-DES encryption algorithms. Triple DES is ei
💻 PY
📖 第 1 页 / 共 2 页
字号:
				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	        24 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.setIV(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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -