How to decrypt unsalted openssl compatible blowfish CBC/PKCS5Padding password in python?
Question: I've been looking for a python library to help decrypt an openssl blowfish
encrypted password.

I have managed to achieve this in Java but the python libraries to support
this appeared more of a learning curve, and required rolling your own.

In terms of what we need to achieve, the password is unsalted and uses a
passphrase, for the purposes of this question I've set this to "AAAAAAAA". The
Cipher is "Blowfish/CBC/PKCS5Padding". The encrypted text will be read in as a
string, same as the key and iv.

In openssl, this is 'simply':

    
    
    ~$ # This is encrypting
    ~$ echo -n 'password' | openssl enc -bf -nosalt -a -K AAAAAAAA -iv AAAAAAAA
    eAIUXziwB8QbBexkiIDR3A==
    ~$ # This is reversing the encryption
    ~$ echo 'eAIUXziwB8QbBexkiIDR3A==' | openssl enc -d -bf -nosalt -a -K AAAAAAAA -iv AAAAAAAA
    password
    

In java, the descryption is along the lines of:

    
    
    private static final String KEY = "AAAAAAAA000000000000000000000000";
    private static final String IV = "AAAAAAAA00000000";
    private static final String FCN = "Blowfish/CBC/PKCS5Padding";
    private static final String CN = "Blowfish";
    
    final byte[] encoded = Base64.decode("eAIUXziwB8QbBexkiIDR3A==");
    final SecretKeySpec key =
    new SecretKeySpec(Hex.decodeHex(KEY.toCharArray()), CN);
    final Cipher cipher = Cipher.getInstance(FCN, JCE_PROVIDER);
    cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(Hex.decodeHex(IV.toCharArray())));
    final byte[] decrypted = cipher.doFinal(encoded);
    return new String(decrypted);
    

Can someone provide some guidance for python?


Answer: Decoding hexadecimal and base64 encoded strings is built-in:

    
    
    In [1]: "AAAAAAAA000000000000000000000000".decode('hex')
    Out[1]: '\xaa\xaa\xaa\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    
    In [2]: "eAIUXziwB8QbBexkiIDR3A==".decode('base64')
    Out[2]: 'x\x02\x14_8\xb0\x07\xc4\x1b\x05\xecd\x88\x80\xd1\xdc'
    

The [PyCrypto](https://www.dlitz.net/software/pycrypto/) library handles
[BlowFish](https://www.dlitz.net/software/pycrypto/api/current/Crypto.Cipher.Blowfish-
module.html) (among others).

    
    
    In [1]: from Crypto.Cipher import Blowfish
    
    In [2]: KEY = "AAAAAAAA000000000000000000000000".decode('hex')
    
    In [3]: IV = "AAAAAAAA00000000".decode('hex')
    
    In [4]: cipher = Blowfish.new(KEY, Blowfish.MODE_CBC, IV)
    
    In [5]: ciphertext = "eAIUXziwB8QbBexkiIDR3A==".decode('base64')
    
    In [6]: cipher.decrypt(ciphertext)
    Out[6]: 'password\x08\x08\x08\x08\x08\x08\x08\x08'
    

If you want to strip off the padding from the plaintext in one go:

    
    
    In [14]: cipher.decrypt(ciphertext).replace('\x08', '')
    Out[14]: 'password'
    

