Decrypting blowfish-ecb with nodejs crypto vs php's mcrypt
Asked Answered
A

2

6

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?

Amadus answered 27/12, 2011 at 18:2 Comment(3)
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.Geology
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().Geology
@Geology 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.Amadus
G
5

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.

Geology answered 27/12, 2011 at 22:10 Comment(2)
It seems that was enough of a push in the right direction. createCipher and createDecipher use a MD5 hash of the key, whereas createCipheriv and createDecipheriv use the raw key and the IV provided. Changing the code to use crypto.createDecipheriv('bf-ecb', 'typeconfig.sys^_-', '') makes it work now. Thanks!Amadus
@Geology Any ideas about this question? #37825761Rey
F
2

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();
Fulvous answered 23/9, 2013 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.