0

I'm trying to recover file encrypted with an old pure python implementation of blowfish.

the old code relied on a single blofish.py file (Copyright (C) 2002 Michael Gilfix )

The old data are encrypted performing following operations:

cipher = Blowfish(self.masterKey)
cipher.initCTR()
cleanData = cipher.decryptCTR(encData)

That code don't initialize the nonce that is required in modern implementation of blowfish, so I was unable to port it to pycryptodome function

cipher = Blowfish.new(self.masterKey, Blowfish.MODE_CTR, nonce = ?????)
cleanData = cipher.decrypt(encData)

The only suggestion that I can find is inside the initCTR function where iv is set to 0 (even if CTR mode don't have IV)

def initCTR(self, iv=0):
  """Initializes CTR mode of the cypher"""
  assert struct.calcsize("Q") == self.blocksize()
  self.ctr_iv = iv
  self._calcCTRBUF()

def _calcCTRBUF(self):
  """Calculates one block of CTR keystream"""
  self.ctr_cks = self.encrypt(struct.pack("Q", self.ctr_iv)) # keystream block
  self.ctr_iv += 1
  self.ctr_pos = 0

can someone help me?

Prev-I
  • 61
  • 8

1 Answers1

2

First, a few warnings:

  1. Blowfish is not a secure cipher by today's standard. Use AES.
  2. Counter mode (CTR) is not secure because it does not detect malicious modification of the encrypted data. Use other modes like GCM, CCM or EAX.
  3. Counter mode really requires a random IV for every message. However, you are using a fixed IV fixed which is very wrong.

To answer your question, you should initialize the cipher as:

from Crypto.Util import Counter

ctr = Counter.new(64, initial_value=0, little_endian=True)
cipher = Blowfish.new(self.masterKey, Blowfish.MODE_CTR, counter=ctr)

The Counter object is documented here. It allows the definition of a little-endian counter (typically CTR is big-endian).

NOTE: blowfish.py encrypts differently in big-endian machines than on little-endian ones.

  • The Idea was to decrypt content and then encrypt using AES to here onward. Your solution work only partially... it decrypt correctly the first 8 chars but then the output is wrong: result: B8-CA-3A½ø0h£B3Æ« - expecting:B8-CA-3A-7E-F0-23 – Prev-I May 03 '18 at 08:41
  • I just noticed that blowfish.sh uses native endianess for the counter, and most likely your data was encrypted in little-endian mode (CTR typically counts in big-endian mode). You therefore need to use Crypto.Util.Counter. – SquareRootOfTwentyThree May 03 '18 at 10:28
  • with counter it work like a charm. Now it's time to upgrade to secure cypher – Prev-I May 03 '18 at 12:01
  • Saying CTR mode is not secure is disingenuous, as authentication may or not be required by the threat model. Also CTR mode can be used securely in an encrypt then MAC environment. Note: I am not in general a proponent of CTR mode. Also many times GCM, CCM or EAX modes are not available. – zaph May 03 '18 at 13:32
  • 1
    @zaph CTR mode alone is "secure-with-a-lot-of-ifs". The average developer has high probability of shooting themselves in the foot, significantly less with GCM/GCM/EAX. – SquareRootOfTwentyThree May 03 '18 at 14:53
  • IMO "The average developer" has a close to zero chance of using crypto primitives to creating a secure system. Best to use well vetted libraries that encompass the whole process including IV/counter creation, authentication and key derivation such as libsodium, RNCryptor, NaCl, etc. – zaph May 03 '18 at 15:18