6
votes

I'm trying to decode the following base64-encoded ciphertext in Node.js with the built-in crypto library

2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==

It seems to work with PHP's mcrypt functions using the string typeconfig.sys^_- as the key, as shown by inputting the value into http://www.tools4noobs.com/online_tools/decrypt/ and selecting Blowfish, ECB, Base64 decode.

However, when I run the following code in Node.js:

var crypto = require('crypto');
var data = "2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==";
var decipher = crypto.createDecipher('bf-ecb', 'typeconfig.sys^_-');
data = decipher.update(data, "base64", "utf8");
data += decipher.final("utf8");
console.log(data);

I get garbage output:

y
�:����d�(����Q�i��z1��4�� �k�(� ��a5����u��73c/��(ֻ��)��������fȠ���
                                                              �ec�-<z�8����(�-L���ԛ�I��1L*��u�4�j-�Чh쭊@\P)?޼�.�^���q㊬�U���W&�x��85�T-ג9,dE<g}�`*�
��|@����k"�!�D'u���,x��7����
                 ��9q=q�q��ա>�w�T����H3͜�i)R��zy��C��
                                                    ��o�

I've also tried a test of the library itself, in that it seems to be able to handle stuff it encodes itself fine:

var crypto = require('crypto')
var cipher = crypto.createCipher("bf-ecb", "key");
var data = cipher.update("foobar", "utf8", "base64");
data += cipher.final("base64");
console.log(data);
var decipher = crypto.createDecipher("bf-ecb", "key");
data = decipher.update(data, "base64", "utf8");
data += decipher.final("utf8");
console.log(data);

produces:

y0rq5pYkiU0=
foobar

but copy-and-pasting that base64 string and inputting it into http://www.tools4noobs.com/online_tools/decrypt/ alongside the key "key" produces garbage output also.

Shouldn't these two libraries produce the same output, or is there something I've done wrong?

2
The documentation for Node.js and PHP's mcrypt are not clear, but it looks like Node.js uses a key derivation function, while mcrypt uses the key as-is. Since Node.js implements PBKDF2, I'm guessing that's its key derivation algorithm, but I don't see how to specify the parameters. You should figure out the parameters it uses, then derive a key given your password, and use that key on the PHP side.erickson
Oh, also, I notice in the working Node.js code, you use createCipher() for encrypting and decrypting, while in your original, not-working code, you are using createDecipher().erickson
@erickson yes, the createCipher twice was a typo, sorry.. My problem is that I'm trying to be compatible with another service that requires that specific raw key (see the first base64 encoded string for the example), so your answer help explains the difference between the two, it doesn't actually help me decode and encode what I need.Adam M-W

2 Answers

5
votes

Node.js computes the MD5 hash of the password before using it as the key. As far as I can tell, mcrypt uses the key as-is.

Compute the MD5 hash of the password, and use that as the mcrypt key.

2
votes

https://github.com/tugrul/node-mcrypt

var mcrypt = require('mcrypt');

var bfEcb = new mcrypt.MCrypt('blowfish', 'ecb');

bfEcb.open('typeconfig.sys^_-');

var cipherText = new Buffer('2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==', 'base64');

console.log(bfEcb.decrypt(cipherText).toString());

bfEcb.close();