Incorrect BlowFIsh Key crashing program


#1

Hello.

When using Blowfish, if the encrypted MemoryBlock is attempted to be decrypted with the wrong keyData, it crashes. I would have thought that if they supplied key didn’t match the encryption key in should return false or similar. Running the correct key runs perfectly. Reduced code:

    const String tempKey = "willwork";
    const String incorrectTempKey = "wontwork";
    
    BlowFish blowFish = BlowFish (&tempKey, static_cast <int>(tempKey.getNumBytesAsUTF8()));
    BlowFish incorrectBlowFish = BlowFish (&incorrectTempKey, static_cast <int> (incorrectTempKey.getNumBytesAsUTF8()));
    
    blowFish.encrypt (memoryblock);
    //blowFish.decrypt (mb);
    incorrectBlowFish.decrypt (memoryblock);

The jassert in ‘void BlowFish::decrypt (MemoryBlock& data) const’ crashes the program.


#2

an assert is not a crash. It is a debugging tool, to let you know something has gone wrong. It does nothing in a release build.


#3

Well, it’s amazing the things you miss when learning I guess!

The Memory block being encrypted is a valuetree. Can one presume then that
the incorrectly decrypted valuetree will be simply incorrect?


#4

Programmers don’t presume anything… either it’ll tell you in the API docs or the source code… if you want to see what’s happening… when you get the assertion start stepping though the code with your debugger and learn what happens.

Rail


#5

Indeed, it was a poor wording of enquiring about the nature of what results from an incorrect description.

I’ve found confirmation of correct or not decryption by calling .hasProperty() on the result.


#6

Just as an explanation, an assert is like a hardcoded conditional breakpoint. It is meant for conditions, that shouldn’t happen in production and to give you the chance to see the code where an assumed condition was not met. You can always just click “continue”.

To help you, usually the juce developers put big comments next to the assert. But not in this case.
But it should be simple enough to deduce the intention of the assert. Unfortunately you didn’t post the line number, so I assume, it happened here:

This means, the decrypt came back with an error code (newSize<0).

I am not aware of an encrypted ValueTree. Usually you serialise a ValueTree to anything you can encrypt. Which format is up to you.
If the deserialisation (i.e. construction of the ValueTree from the data using ValueTree::fromXML, readFromData or readFromStream etc. fails, you get myValueTree.isValid() == false. That’s better than to check for random properties.


#7

Thank you Daniel for your help! That makes far more sense to me now and will help a lot.

I am not aware of an encrypted ValueTree.

It’s not encrypted directly, I wrote it to a MemoryBlock using a MemoryOutputStream and encrypted it that way as I wanted it locked with a key.

If the deserialisation (i.e. construction of the ValueTree from the data using ValueTree::fromXML, readFromData or readFromStream etc. fails, you get myValueTree.isValid() == false. That’s better than to check for random properties.

Strangely, when decrypted using the MemoryBlock method .isValid() came back true, even through the decryption failed. It seems to work reliably as it is.


#8

If you use MemoryOutputStream/MemoryInputStream the read memory will probably simply be interpreted as ValueTree. isValid() only checks whether ValueTree::object is not nullptr. Since something decrypted with a wrong key is more or less random chances are very high that this is the case.
It will still crash if you’d use this ValueTree.

That’s the reason for using some serialisation where the decrypted data can easily be checked (it’s unlikely you’d get a valid XML document when applying a wrong key).