From http://www.strategyonline.co.za/accessories/jblowfish/

J-Blowfish is a Clarion wrapper (pure Clarion source, no black boxes) for the Blowfish  encryption algorithm. Most of this code was written by Andy Ireland  – we have added a helper class, examples, templates, etc.

I learnt a lot looking into this code a few years ago (wow, it was 2006 looking at my notes!). At the time we needed an implementation of the Blowfish Encryption Algorithm to share encrypted data between a Clarion and Java application. J-Blowfish seemed like a great fit but unfortunately we found that it was not producing standard encrypted data and was also unable to decrypt anything produced by another implementation.

The solution at the time was to use a C DLL instead. This worked fine but seemed a bit ugly, I would have much preferred a pure clarion solution. Also, the code in  jblowfish.clw intrigued me.

NOTE: This is just me poking around in things to learn something new. Don’t blame me if following anything in this blog sinks your submarine or whatever 🙂

Here is what I found…

(It is simpler to deal with hex output so that is the only section I have looked at but the results impact all encrypt/decrypt functions.)

1st, Implementation problem:

(In the “Main” procedure of BlowDemo.app)

In the demo supplied with J-Blowfish the local variable holding the key is not clipped. This means the actual key used for the Encryption is inclusive of the trailing spaces in the STRING.

Additionally, the blowfish encryption mode implemented in J-Blowfish (which I believe is ECB) requires your data to be a multiple of 8 bytes. The original implementation will pad an extra 8 bytes if the data is already a multiple of 8.

Original:

Suggested improvements:

2nd, Encryption problem (jblowfish.clw)

The “BlowFish._Encrypt” method seems to be the culprit in the encryption errors I experienced.

In my testing I was using this data:

key: “abc”

plain text: “abcdefgh”

encrypted result (other tools): “94c559d64e1251fb”

I discovered that if in the BlowDemo.exe I used this data, “dcbahgfe” I would get the correct result (almost… the result was also backwards “d659c594 fb51124e”)

So it came down to a problem with the way the data was being passed to the “self.BF_Encrypt(pWork, pWork2)” part of this method.

(note: the BF_Encrypt method is used successfully in the BlowFish.Initialise method, I checked the values being generated and they are all correct)

Basically I believe this is because the Endianness of clarion longs is different to whatever assumption is made in the algorithm J-.Blowfish is based upon.

This is what I came up with:

Other considerations:

  • This only takes care of the Encryption phase something similar will need to happen in the Decrypt method.
  • There may be better ways (band, bshift, bxor, whatever) to do this but it was late and this way is at least descriptive 😉
  • I passed a few of the standard test vectors through the changed version and it seems to work correctly now. Most implementations have in them somewhere a self test method that uses these test vectors to prove they are running correctly:

    http://www.schneier.com/blowfish.html

    http://www.schneier.com/code/vectors.txt

  • One thing I learned (amongst many!) whilst doing all this. It seems you can safely do a search replace in jpwbfish.inc and jpwbfish.clw to replace all ULONG’s with LONG’s. This may even result in some speed improvements as supposedly longs are faster then ulongs. Reason for this is that longs are 32 bit and that is sufficient for blowfish as it works in 32 bit words. It seemed weired to me at first, its like when you do this:

But blowfish doesn’t care about the +/- part as it is working directly on the bytes in the long, thus a LONG is sufficient.

(This explanation may be off on a few technical points but you get the drift?)

I hope all the above makes (some) sense!

-brahn