Blowfish Encryption Python

1 view
Skip to first unread message

Dona Vansoest

unread,
Aug 5, 2024, 4:45:17 AM8/5/24
to athcheynofor
Iam attempting to convert my Java Blowfish encryption algorithm into Python. I am using the blowfish package which takes the same parameters as the Java library. They both execute successfully, however, I do not get the same result back.

I'm trying to understand why there is a difference between Ruby and

Python when using Blowfish encryption in ECB mode. Using the same

algorithm parameters, and the same input, the encrypted output is

completely different.


Why is this happening? This is a major pain as it means I cannot interop

with Python. There are other gems for Blowfish encryption, but none of

them have ECB mode (which is the one I'm interested in - and yes, before

you say it, I know ECB is insecure).


I don't that's the case... if you look closely you will see I'm setting

the key after calling encrypt. In any case, I've tried swapping them

(setting the key first, then calling encrypt) and I actually get the

same result.


I'm trying to understand why there is a difference between Ruby and

Python when using Blowfish encryption in ECB mode. Using the same

algorithm parameters, and the same input, the encrypted output is

completely different.


Why is this happening? This is a major pain as it means I cannot interop

with Python. There are other gems for Blowfish encryption, but none of

them have ECB mode (which is the one I'm interested in - and yes, before

you say it, I know ECB is insecure).


It seems that the Ruby OpenSSL makes some assumptions with regards to

key length - I'm not sure if this is a bug or not. The fix for the code

I pasted before was very simple: when initializing the cipher, I have to

specify the key_len before setting the key:


imho, ruby follows standard behaviour by padding (padding=1),

[python does not follow standard]

just because ruby's result differs from that of python, doesnt mean

that ruby is wrong, no? anyway, you can ask the core team, they are

always happy to help.

see eg Using padding in encryption


And anyway, you probably should be using full disk encryption and more carefully vetted crypto such as OpenPGP. The reason cryptmethod=blowfish2 exists to begin with is that cryptmethod=blowfish was horribly broken. And it's not compatible with anything.


The issue was that CentOS 7 ships with VIM 7.4.160, as Michael Hampton points out we need 7.4.401. In a comment I mention how to install the later VIM, here are the complete instructions for those who might follow in my footsteps. All credit goes to Michael for identifying the issue and to this Gist for laying out the proper configure line:


Personally, I would avoid multiple encryption protocols most of the time. It adds significant extra implementation complexity without making your data any more secure in the real world, unless the encryption protocol you are using is ultimately broken or becomes computationally feasible at a later date to break.


Granted, I will disagree with others who claim that by doing so you have a larger attack surface and increase your vulnerabilities. While the attack surface technically does increase (you can attack blowfish; you can attack AES), since you must successfully attack both your security has not decreased. (Assuming your message is multiply-encrypted in a nested fashion (anything else doesn't make sense) with independent keys/passphrases like multiply_encrypted_file = Blowfish(AES(file)). If an attacker gets a hold of multiply_encrypted_file it is not in any way weaker than getting hold of encrypted_file = AES(file) though you should beware of exposing yourself to known-plaintext attacks which could weaken security if you used the same key/passphrase at all levels and have a guessable header/structure of the file after the first level of decryption). Even if they find a exploitable flaw in Blowfish encryption, they still only can reverse that and then find an AES encrypted file.


However, I do use multiple layers of encryption on an almost daily basis when there is a legitimate reason for it and it provides extra security. For example, I often need to connect to work computers from my home, but for security the work computers are on a private intranet, firewalled off from the outside world.


To connect, I first create a VPN tunnel over the public internet to a public facing VPN-server that verifies my identity that acts as a gateway to the intranet. Then all my network traffic sent over the internet between my house and work encrypted using IPsec protocol by VPN to the VPN server which decrypts it and forwards it to the local machine as if it was on the local intranet. However, I may then want to connect to something at work using ssh or https. This provides a layer of encryption for the local intranet at work, so my coworkers could not say eavesdrop in on my network connections. However, to someone at my ISP capturing packets the data they see has been multiply encrypted: VPN_encryption(ssh_encryption(actual_data_to_be_transferred)). Again, I'm not using the ssh protocol (on top of VPN) to make my data more secure against my ISP eavesdropping; but in no way does it make it easier for my ISP to eavesdrop).


I don't see how the multiply-encrypted implementation has more of an attack surface and is in anyway weaker than a singly-implemented one. The implementation to the outside world can still be enter a password to decrypt a stored file.


AES128-CBC is strong. If you're implementing it properly, and using strong random keys and unique random IVs, you're very safe. The US government (NSA) certifies AES for use in securing top-secret documents. I somewhat doubt that your security requirements are anywhere near theirs, so you should consider AES more than strong enough alone. If you're really paranoid, move up to 256-bit AES.


Chaining algorithms only provides more provable security if you use independent keys for each. Using the same key for all ciphers means you still only have to bruteforce one key, though at 128 bits it's been predicted that we might never posess the equipment to do so.


Chaining multiple algorithms makes some sense in ridiculously high-security high-paranoia long term storage situations like TrueCrypt volumes, where the deployment environment is completely unknown. However, unless you're likely to be storing military secrets that'll be shipped into a hostile country, and happen to be a professional cryptographer, I'd stick with just using AES.


It is extremely rare that the algorithm itself is a vulnerability. Even weak algorithms such as RC4 are often the strongest part of the system in which they are used. Vulnerabilities usually hide in how you apply encryption (padding, IV randomness, integrity checks...) and in key management. These seemingly peripheral activities are quite hard to do right, and have repeatedly proven to be the number one source of weakness in any encryption system. By encrypting three times, you have tripled the opportunities for such nasty weaknesses.

3a8082e126
Reply all
Reply to author
Forward
0 new messages