How to decrypt using Blowfish in Pycrypto?

14,192

Let's make some observations:

  • CBC mode needs an Initialization Vector (IV) that has the same length as the block size
  • the full plaintext is the actual message including padding (PKCS#5 padding in RFC 2898 Sec. 6.1.1 Step 4)
  • the IV is prepended to the ciphertext

What needs to be done:

  • Use the same key
  • Read the IV before creating the decryptor
  • Remove padding after decryption by looking at the last byte, evaluate that as an integer and remove as many bytes from the end of the plaintext

Code:

from Crypto.Cipher import Blowfish
from struct import pack

bs = Blowfish.block_size
key = b'An arbitrarily long key'
ciphertext = b'\xe2:\x141vp\x05\x92\xd7\xfa\xb5@\xda\x05w.\xaaRG+U+\xc5G\x08\xdf\xf4Xua\x88\x1b'
iv = ciphertext[:bs]
ciphertext = ciphertext[bs:]

cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
msg = cipher.decrypt(ciphertext)

last_byte = msg[-1]
msg = msg[:- (last_byte if type(last_byte) is int else ord(last_byte))]
print(repr(msg))
Share:
14,192

Related videos on Youtube

Manuj Mittal
Author by

Manuj Mittal

Updated on June 04, 2022

Comments

  • Manuj Mittal
    Manuj Mittal almost 2 years

    I found one example to encrypt the data but I am unable to find any example on how to decrypt it.

    Encryption Example:

    >>> from Crypto.Cipher import Blowfish
    >>> from Crypto import Random
    >>> from struct import pack
    >>>
    >>> bs = Blowfish.block_size
    >>> key = b'An arbitrarily long key'
    >>> iv = Random.new().read(bs)
    >>> cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
    >>> plaintext = b'docendo discimus '
    >>> plen = bs - divmod(len(plaintext),bs)[1]
    >>> padding = [plen]*plen
    >>> padding = pack('b'*plen, *padding)
    >>> msg = iv + cipher.encrypt(plaintext + padding)
    

    I did not find any example on how to decrypt.

  • Manuj Mittal
    Manuj Mittal over 8 years
    >>> msg = msg[:-ord(msg[-1])] Traceback (most recent call last): File "<pyshell#57>", line 1, in <module> msg = msg[:-ord(msg[-1])] TypeError: ord() expected string of length 1, but int found
  • Artjom B.
    Artjom B. over 8 years
    Yeah, in Python 3 you have to remove ord, because msg[-1] is already an integer. I've also updated the code so that it works with Python2 and Python 3