Skip to content

Instantly share code, notes, and snippets.

@lopes
Last active August 7, 2024 13:42
Show Gist options
  • Save lopes/168c9d74b988391e702aac5f4aa69e41 to your computer and use it in GitHub Desktop.
Save lopes/168c9d74b988391e702aac5f4aa69e41 to your computer and use it in GitHub Desktop.
Simple Python example of AES in CBC mode. #python #cryptography #aes #cbc #poc
#!/usr/bin/env python3
#
# This is a simple script to encrypt a message using AES
# with CBC mode in Python 3.
# Before running it, you must install pycryptodome:
#
# $ python -m pip install PyCryptodome
#
# Author.: José Lopes
# Date...: 2019-06-14
# License: MIT
##
from hashlib import md5
from base64 import b64decode
from base64 import b64encode
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
class AESCipher:
def __init__(self, key):
self.key = md5(key.encode('utf8')).digest()
def encrypt(self, data):
iv = get_random_bytes(AES.block_size)
self.cipher = AES.new(self.key, AES.MODE_CBC, iv)
return b64encode(iv + self.cipher.encrypt(pad(data.encode('utf-8'),
AES.block_size)))
def decrypt(self, data):
raw = b64decode(data)
self.cipher = AES.new(self.key, AES.MODE_CBC, raw[:AES.block_size])
return unpad(self.cipher.decrypt(raw[AES.block_size:]), AES.block_size)
if __name__ == '__main__':
print('TESTING ENCRYPTION')
msg = input('Message...: ')
pwd = input('Password..: ')
print('Ciphertext:', AESCipher(pwd).encrypt(msg).decode('utf-8'))
print('\nTESTING DECRYPTION')
cte = input('Ciphertext: ')
pwd = input('Password..: ')
print('Message...:', AESCipher(pwd).decrypt(cte).decode('utf-8'))
@DineshGuptaa
Copy link

Hello Mark,

Thanks for your guide !!

Key should be create as below algorithm:

Secret Key Creation is as follow:
16 Character Static String ("Mu8weQyDvq1HlAzN")
16 Character from end of Token
    token_str = "iNGRmNzJiNGM2NWUxM2I1ZGJmOTk4ZTVhYzUwYzYwYmM5MyIsImp0aSI6IjRjMmFkYmY2LTUxYjEtNGE3My04YjdhLWY1MDZhMmUwNjkzYSIsImlhdCI6MTU3ODQ4ODYyM30.SAjMKd0chcAWoFwMkfxJ-Z1lWRM9-AeSXuHZiXBTYyo"

Converting above both string to Hex Code

(hex[Static_String])XOR(hex[Last 16 characters of SSO Token]) 

Java code working fine for key creation:

public  byte[] toHexadecimal(String text) throws UnsupportedEncodingException {
	byte[] myBytes = text.getBytes("UTF-8");
	return myBytes;
}

public  byte[] xorHex(byte[] a, byte[] b) throws UnsupportedEncodingException {
	byte[] result = new byte[16];
	int i = 0;
	for (byte Ab : a) {
		result[i] = (byte) (Ab ^ b[i++]);
	}
	return result;
}

Hex function creation create key as below:

    byte[] statickeyHEX = ob.toHexadecimal("Mu8weQyDvq1HlAzN");
byte[] ssoTokenHEX = ob.toHexadecimal(sso);
byte[] secretKey = ob.xorHex(statickeyHEX, ssoTokenHEX);
System.err.println("Secret Key>>>>>>>>>>>>>>"+secretKey);

Output of Secret Key = [B@7852e922

But in Python different. Please guide me to create key

@DineshGuptaa
Copy link

DineshGuptaa commented Jan 11, 2020

I have found the solution that work perfectly for me:
Code Reference : https://yococoxc.github.io/15493867450071.html

import Crypto.Cipher.AES
import Crypto.Random
import base64
import binascii


class Cipher_AES:
	pad_default = lambda x, y: x + (y - len(x) % y) * " ".encode("utf-8")
	unpad_default = lambda x: x.rstrip()
	pad_user_defined = lambda x, y, z: x + (y - len(x) % y) * z.encode("utf-8")
	unpad_user_defined = lambda x, z: x.rstrip(z)
	pad_pkcs5 = lambda x, y: x + (y - len(x) % y) * chr(y - len(x) % y).encode("utf-8")
	unpad_pkcs5 = lambda x: x[:-ord(x[-1])]

	def __init__(self, key="abcdefgh12345678", iv=Crypto.Random.new().read(Crypto.Cipher.AES.block_size)):
		self.__key = key
		self.__iv = iv

	def set_key(self, key):
		self.__key = key

	def get_key(self):
		return self.__key

	def set_iv(self, iv):
		self.__iv = iv

	def get_iv(self):
		return self.__iv

	def Cipher_MODE_ECB(self):
		self.__x = Crypto.Cipher.AES.new(self.__key.encode("utf-8"), Crypto.Cipher.AES.MODE_ECB)

	def Cipher_MODE_CBC(self):
		self.__x = Crypto.Cipher.AES.new(self.__key.encode("utf-8"), Crypto.Cipher.AES.MODE_CBC,
										 self.__iv.encode("utf-8"))

	def encrypt(self, text, cipher_method, pad_method="", code_method=""):
		if cipher_method.upper() == "MODE_ECB":
			self.Cipher_MODE_ECB()
		elif cipher_method.upper() == "MODE_CBC":
			self.Cipher_MODE_CBC()
		cipher_text = b"".join([self.__x.encrypt(i) for i in self.text_verify(text.encode("utf-8"), pad_method)])
		if code_method.lower() == "base64":
			return base64.encodebytes(cipher_text).decode("utf-8").rstrip()
		elif code_method.lower() == "hex":
			return binascii.b2a_hex(cipher_text).decode("utf-8").rstrip()
		else:
			return cipher_text.decode("utf-8").rstrip()

	def decrypt(self, cipher_text, cipher_method, pad_method="", code_method=""):
		if cipher_method.upper() == "MODE_ECB":
			self.Cipher_MODE_ECB()
		elif cipher_method.upper() == "MODE_CBC":
			self.Cipher_MODE_CBC()
		if code_method.lower() == "base64":
			cipher_text = base64.decodebytes(cipher_text.encode("utf-8"))
		elif code_method.lower() == "hex":
			cipher_text = binascii.a2b_hex(cipher_text.encode("utf-8"))
		else:
			cipher_text = cipher_text.encode("utf-8")
		return self.unpad_method(self.__x.decrypt(cipher_text).decode("utf-8"), pad_method)

	def text_verify(self, text, method):
		while len(text) > len(self.__key):
			text_slice = text[:len(self.__key)]
			text = text[len(self.__key):]
			yield text_slice
		else:
			if len(text) == len(self.__key):
				yield text
			else:
				yield self.pad_method(text, method)

	def pad_method(self, text, method):
		if method == "":
			return Cipher_AES.pad_default(text, len(self.__key))
		elif method == "PKCS5Padding":
			return Cipher_AES.pad_pkcs5(text, len(self.__key))
		else:
			return Cipher_AES.pad_user_defined(text, len(self.__key), method)

	def unpad_method(self, text, method):
		if method == "":
			return Cipher_AES.unpad_default(text)
		elif method == "PKCS5Padding":
			return Cipher_AES.unpad_pkcs5(text)
		else:
			return Cipher_AES.unpad_user_defined(text, method)


def main2(msg, token):
	st_arr = []
	dy_arr = []
	static_str = 'Mu8weQyDvq1HlAzN'
	for b in bytearray(static_str, "utf-8"):
		st_arr.append(b)

	token_str = token[-16:]
	for b in bytearray(token_str, "utf-8"):
		dy_arr.append(b)

	res_byts = []
	for bt in bytes(a ^ b for (a, b) in zip(st_arr, dy_arr)):
		res_byts.append(bt)

	key = bytes(res_byts).decode()
	iv = key 
	text = msg  # "7977099688"
	cipher_method = "MODE_CBC"
	pad_method = "PKCS5Padding"
	code_method = "base64"
	cipher_text = Cipher_AES(key, iv).encrypt(text, cipher_method, pad_method, code_method)
	cipher_text = cipher_text.replace('\n', '')
	print('[' + cipher_text + ']')
	print(type(cipher_text))
	text = Cipher_AES(key, iv).decrypt(cipher_text, cipher_method, pad_method, code_method)
	print(text)


if __name__ == '__main__':
	main2("405862999990475",
		  "CI6MTU3ODQ4ODYyM30.SAjMKd0chcAWoFwMkfxJ-Z1lWRM9-AeSXuHZiXBTYyo")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment