NeuroTheGreat
NeuroTheGreat

Reputation: 97

AES OFB implementation in python with pycryptodome

I am trying to implement the OFB mode of AES encryption using the pycryptodome library and I'm having issues with understanding what input should i give to the cipher. I know that pycryptodome already has OFB implemented but I need to take the plain text break it into bytes, apply the proper steps of OFB to encrypt it with an AES cipher with ECB mode and then decrypt it.

How do byte strings such as b'\x16\xa8W\xed.)\xc4\xb8x\xd6\xcf\x7f\xf3\xe3;^' work in python?

I need to take such a byte string, encrypt it, then break it in half and XOR it with the 8 bytes of the plain text. Easiest way for me to understand and do this would be to have the IV (the byte string from above) encrypted with AES, then convert it and the plain text to binary and xor them and then convert them back to bytestrings. How can I do that?

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

plainText = b"Lorem ipsum dolor sit amet, consectetur adipiscing e"
key = b"ANAAREMEREAAAAAA"
iv = get_random_bytes(32)

print("iv: ", iv)

cipher = AES.new(key, AES.MODE_ECB)
toXor = cipher.encrypt(iv)

print("toXor: ", toXor)

"""
toXorF=first half of toXor
ivS=second half of iv

cipherText=toXorF xored to first 8 bytes of plainText
iv=ivS + toXorS
"""

Output of prints:

iv:  b"v'xg;\xd7h\xfc\xf2\xa4[\r\xee]J\x1eu\xa5\xe68\xa3a\xde\x02(\xc1\xe0\xc9z\x0f\xc3n"
toXor:  b'\x97\xbex\xfc\xb6\xbb\x85\xccZ\xc4\xe4\x9d\xd6M\xf2\xd7\xb7\xbf\xd0\xbe\xa5A\xd6\xee\x07U\xe0S\x7f\x88\xea\xcd'

If you have any suggestions for a better architecture of my program/approach to my problem feel free to enlighten me.

Upvotes: 1

Views: 2884

Answers (1)

NeuroTheGreat
NeuroTheGreat

Reputation: 97

I applied what t.m.adam suggested and this is the final code which works perfectly.

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

plainText = b"Lorem ipsum dolor sit amet, consectetur adipiscing e"
key = b"ANAAREMEREAAAAAA"


def ofbEnc(plainText, key):
    pos = 0
    cipherTextChunks = []
    iv = get_random_bytes(16)
    originalIV = iv
    cipher = AES.new(key, AES.MODE_ECB)
    if len(plainText) % 16 != 0:
        plainText += b"1"
    while len(plainText) % 16 != 0:
        plainText += b"0"
    while pos + 16 <= len(plainText):
        toXor = cipher.encrypt(iv)
        nextPos = pos + 16
        toEnc = plainText[pos:nextPos]
        cipherText = bytes([toXor[i] ^ toEnc[i] for i in range(16)])
        cipherTextChunks.append(cipherText)
        pos += 16
        iv = toXor
    return (originalIV, cipherTextChunks)


def ofbDec(cipherTextChunks, key, iv):
    plainText = b""
    cipher = AES.new(key, AES.MODE_ECB)
    for chunk in cipherTextChunks:
        toXor = cipher.encrypt(iv)
        plainText += bytes([toXor[i] ^ chunk[i] for i in range(15)])
        iv = toXor
    while plainText[-1] == 48:
        plainText = plainText[0:-1]
    if plainText[-1] == 49:
        plainText = plainText[0:-1]
    return plainText


iv, result = ofbEnc(plainText, key)
print(iv, result)

plain = ofbDec(result, key, iv)
print(plain)

Upvotes: 4

Related Questions