2

This is 3DES using crypto (base on OpenSSL) in native Node.js.

var secretKey         = "efd77bed61e8fdd0437df1ac";
var enchding          = 'hex';
var text              = 'This is test.';
var cipher            = modules.crypto.createCipher('des-ede3-cbc', secretKey);
var cryptedPassword   = cipher.update(text, 'utf8', enchding) + cipher.final(enchding);

output is : af4ee52e0227fe40ab2e7ddd72fb1137


But I used online PHP-mcrypt encrypt tool (link here).

Key is efd77bed61e8fdd0437df1ac

Algorithm is Tripledes, mode is CBC and output using Hexa.

output is : d4b374b7ac8df7883ab1d58c7db0b0cc


Why does both of these are different results?

And how can I get the same result using crypto in Node.js?

1 Answer 1

3

There are multiple issues with your code.

  • crypto.createCipher(algorithm, password) uses a password not a key. The actual key will be derived from that password. It seems that you want to use a key instead of a password, so you need to use crypto.createCipheriv(algorithm, key, iv).

  • PHP's mcrypt module only applies zero padding, but node.js' crypto module only applies PKCS#5/PKCS#7 padding. You should use PKCS#7 padding in PHP like shown here. (used in the example code)

  • You have to use the same IV in both node.js and PHP. Usually a random IV is generated and prepended to the ciphertext. During decryption it must be sliced off and used. (not included in the example code)

node.js

var crypto = require('crypto');

var secretKey         = new Buffer("efd77bed61e8fdd0437df1ac", "utf8");
var iv                = new Buffer("\0\0\0\0\0\0\0\0");
var enchding          = 'hex';
var text              = 'This is test.';
var cipher            = crypto.createCipheriv('des-ede3-cbc', secretKey, iv);
var cryptedPassword   = cipher.update(text, 'utf8', enchding) + cipher.final(enchding);

console.log(cryptedPassword);

output:

4e91635045f42185831403057ef16749

PHP

function pkcs7pad($plaintext, $blocksize)
{
    $padsize = $blocksize - (strlen($plaintext) % $blocksize);
    return $plaintext . str_repeat(chr($padsize), $padsize);
}

$pt = pkcs7pad('This is test.', 8);
$iv = '\0\0\0\0\0\0\0\0';
$key = 'efd77bed61e8fdd0437df1ac';

$ct = mcrypt_encrypt(MCRYPT_3DES, $key, $pt, MCRYPT_MODE_CBC, $iv);

echo bin2hex($ct);

output:

4e91635045f42185831403057ef16749

It seems you want to encrypt passwords. Passwords should never be encrypted. Use a good hashing solution like PBKDF2, bcrypt or scrypt and verify the password by hashing it again.

Sign up to request clarification or add additional context in comments.

2 Comments

How do I tell node.js to use PKCS#5?
@majidarif PKCS#5 and PKCS#7 paddings are equivalent (actually, there is no such thing as PKCS#5 padding for AES). node.js uses PKCS#7 by default

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.