0

Hi i have written a code in python2 with pycrypto to encrypt and decrypt from a string here is the code

hex_key_bytes = array.array('B', [0xb8, 0xf4, 0xc9, 0x57, 0x6e, 0x12, 0xdd, 0x0d,0xb6, 0x3e, 0x8f, 0x8f, 0xac, 0x2b, 0x9a, 0x39]); # Python 2
hex_iv_bytes = array.array('B', [0xc7, 0x0f, 0x09, 0x5d, 0x8b, 0xb1, 0xa0, 0x60, 0x69, 0x9f, 0x7c, 0x19, 0x97, 0x4a, 0x1a, 0xa0]) # Python 2
BLOCK_SIZE = 16  



# Decryption Functions - START
def decrypt_message(message):
    encrypted_msg = message;
    cipher = AES.new(hex_key_bytes, AES.MODE_CBC, hex_iv_bytes);
    test = cipher.decrypt(encrypted_msg.decode('hex')) #.rstrip('\x00')
    filtered_string =filter(lambda x: x in string.printable, test)
    return filtered_string
# Decryption Functions - END


#Encryption Functions - START
#pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
#                chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)

pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
                chr(0)

unpad = lambda s: s[:-ord(s[len(s) - 1:])]

def encrypt_msg(message):
    raw = pad(message)
    while(len(raw) != 48):
        raw = raw+chr(0)
    cipher = AES.new(hex_key_bytes, AES.MODE_CBC, hex_iv_bytes) 
    encrypted_msg = (cipher.encrypt(raw)).encode("hex")
    #logger.info("Writing encrypted packet to device " +encrypted_msg)
    return encrypted_msg

I am trying to migrate the solution in python3

Here are the changes I have made

from Crypto.Cipher import AES
import string

BLOCK_SIZE = 16  

hex_key_bytes = 'b8f4c9576e12dd0db63e8f8fac2b9a39'
hex_iv_bytes =  'c70f095d8bb1a060699f7c19974a1aa0'

hex_key_bytes = bytes.fromhex(hex_key_bytes)
hex_iv_bytes = bytes.fromhex(hex_iv_bytes)


# Decryption Functions - START
def decrypt_message(message):
    encrypted_msg = message;
    cipher = AES.new(hex_key_bytes, AES.MODE_CBC, hex_iv_bytes);
    test = cipher.decrypt(encrypted_msg.fromhex()) #.rstrip('\x00')
    filtered_string =filter(lambda x: x in string.printable, test)
    return filtered_string
# Decryption Functions - END


#Encryption Functions - START
#pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
#                chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)

pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
                chr(0)

unpad = lambda s: s[:-ord(s[len(s) - 1:])]

def encrypt_msg(message):
    raw = pad(message)
    while(len(raw) != 48):
        raw = raw+chr(0)
    cipher = AES.new(hex_key_bytes, AES.MODE_CBC, hex_iv_bytes)
    print(cipher.encrypt(raw))  
    encrypted_msg = (cipher.encrypt(raw)).hex()
    #logger.info("Writing encrypted packet to device " +encrypted_msg)
    return encrypted_msg

but the problem i am facing is encrypted string is not the same for both

same text in

python3 --> 39c457ed7a0b6c61b936d538f9cd7815b48e674ead3cb810f20f57899c4a1b980d3206e421f045758a5ef07efd35e55f

python3 -> 6055565cab3ae7229c8148d32d4f3397477b9cdf6b91252900c95d7509e52e80f6f42227d9b111176f6b662113900fb7

How can I solve that?

ArnabGhosh
  • 35
  • 6
  • The `cipher`-object is _stateful_. Therefore remove the line `print(cipher.encrypt(raw))` in the 2nd snippet and compare the results again. Alternatively, a new `cipher`-object can be created after the `print`-call. – Topaco Jan 09 '20 at 10:17
  • yes, I have done that and solved the purpose. but still stuck at decrypt function as .decode('hex') is not supported by python 3 and what I have tried .hex() instead, but not getting the proper result. what I have achieved, both encryption function is generating same result. – ArnabGhosh Jan 09 '20 at 11:19
  • For Python3, replace `encrypted_msg.fromhex()` with `bytes.fromhex(encrypted_msg)`, [here](https://stackoverflow.com/a/5682984/9014097). Another advice: Use PKCS7 padding instead of zero padding, [here](https://en.wikipedia.org/wiki/Padding_(cryptography)). PKCS7 is reliable and is supported by PyCryptodome, [here](https://pycryptodome.readthedocs.io/en/latest/src/util/util.html#crypto-util-padding-module). – Topaco Jan 09 '20 at 12:13
  • thanks solved the issue – ArnabGhosh Jan 14 '20 at 11:18

1 Answers1

0
import ast
from base64 import b64encode

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers import algorithms
from cryptography.hazmat.primitives.ciphers import modes



def encryptor(data):

    """
    return encrypt data using AES algorithm
    """

    key = 'your_key'[:32]
    iv = 'your_iv'[:16]

    iv = str(iv).encode("utf-8")
    key = str(key).encode("utf-8")
    data = json.dumps(data)
    data = data.encode("utf-8")
    padder = padding.PKCS7(128).padder()
    message_encrypt = padder.update(data) + padder.finalize()
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
    encryptor_cipher = cipher.encryptor()
    ct = encryptor_cipher.update(message_encrypt) + encryptor_cipher.finalize()
    ct_out = b64encode(ct)
    return ct_out


def decryptor(data):

    """
    return decrypt data using AES algorithm
    """

    key = 'your_key'[:32]
    iv = 'your_iv'[:16]

    iv = str(iv).encode("utf-8")
    key = str(key).encode("utf-8")
    unpadder = padding.PKCS7(128).unpadder()
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
    decryptor_cipher = cipher.decryptor()
    ct = b64decode(data)
    plain = decryptor_cipher.update(ct) + decryptor_cipher.finalize()
    plain = unpadder.update(plain) + unpadder.finalize()
    plain = plain.decode('utf-8')
    plain = json.dumps(plain)
    plain = json.loads(plain)
    plain = ast.literal_eval(plain)
    plain = ast.literal_eval(json.dumps(plain))
    return plain
Roshan
  • 27
  • 1
  • 6