Last active
August 7, 2024 13:42
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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')) |
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
Hello Mark,
Thanks for your guide !!
Key should be create as below algorithm:
Converting above both string to Hex Code
Java code working fine for key creation:
Hex function creation create key as below:
But in Python different. Please guide me to create key