3
votes

I have a delphi application that uses the Delphi Encryption Compendium (DEC) to encrypt some data. It works very well, and I can encrypt and decrypt without any trouble. I am using Rijndael encryption.

My challenge is to decrypt the encrypted-with-Delphi data with Node.JS (using the functionality in crypto). I've looked at the StackOverflow questions Delphi DEC library (Rijndael) encryption and AES encrypt in Node.js Decrypt in PHP. Fail., and I think I'm understanding my issue a little better.

What I've learned is that I need to mimic the key derivation used by DEC on the node side. I cannot override or change in any way the encryption side.. I have to work with what is already there.

My question is: Is the key derivation used by DEC (given a key and iv) standard, or is it something used exclusively by the DEC library? If it's standard, has anyone seen any javascript code that produces the same output as the function in DEC, given the same inputs?

I see that part of the key derivation sequence involves hashing the key (in this case, a 32-byte key, hashed with RipeMD-256). I see further that the size of the key is reduced from 32 bytes to 16 as part of the key derivation process. Where I'm getting tripped up in the Delphi code is how DEC uses the key and the iv to derive the key actually used for decrytpting.

I'm happy to edit this with any necessary code. I'm hoping someone familiar with the DEC library - and javascript / node.js - can point me in the right direction.

===Edit===

So after some additional digging, I came across this Javascript code for AES as an alternative to working with the crypto module. The author takes the CIV value to be the first eight bytes of the encrypted text, so I just:

var encryptedData='B6F03982E2F6303ACA7313';  // plain text is 'Hello There'
var key='01234567890123456789012345678901';
var hashedKey=hash('ripemd256',key);
var civ='549621EEF38647BE';
var decryptedData='';

var charEncryptedData=hex2a(encryptedData);
var charKey=hex2a(hashedKey);
var charCiv=hex2a(civ);

decryptedData=Aes.Ctr.decrypt(charCiv+charEncryptedData,hashedKey,128);

console.log('decrypted data: '+decryptedData);

But after all this, I'm left wondering if the key derivation in this library is the same as that in the DEC.

=== Edit ===

In answer to a comment, no, it appears the two implementations do NOT compute the same encrypted data given the same key and civ values. Calling

var reEncryptedData=Aes.Ctr.encrypt('hello there', charKey, 128, charCiv);

yields a completely different encrypted string which, even accounting for the prepending of the CIV to the encrypted text, is still 8 bytes longer than the output from the delphi side.

===Edit===

Aes.Ctr code library (mentioned above) is using the CTR mode, where I'm doing CBC on the delphi side. -sigh-

Thanks again.

2
Wouldn't the determination of whether the two implementations are compatible just be a matter of encrypting with both using the same key/iv pair and see if the outputs are identical?500 - Internal Server Error
question has been edited to address this comment. Short answer is - No, they are not the same!Chris
Sounds like one of these libraries does not conform to the AES specification. So now you need to find a third one to determine which one works and which one doesn't :)500 - Internal Server Error
And then possibly a fourth to verify the operation of 1 & 3!Chris

2 Answers

0
votes

You can compare the algorythm with these two javascript libraries:

Both definitly produce correctly crpyted output.

BTW: The first one is used by MEGA (KimDotCom) for his file encryption.

1
votes

I'm sure it's not the whole answer, but it's part of one.

In comparing the various Javascript AES implementations, including those submitted by heinob to this question, I found some differences between those and the Delphi version. Particularly in some of the precomputed values.

So, I had two choices: re-develop the code in the Delphi library or build a DLL from the Delphi library, and call it from a dot net app. I decided to go the dot net route: build a dll that calls the decrypt route in the Delphi library.

If anyone else goes this route, I will pass along a couple tidbits:

my function signature was:

function decrypt(encryptedData, key, iv: PAnsiChar): PAnsiChar; StdCall; Export;

In C#, the function signature was:

public static extern IntPtr decrypt(string encryptedData, string key, string iv);

After calling, you marshal the IntPtr to an ansi string..