将PHP的mcrypt_encrypt()与node.js相匹配crypto.createCipher()

时间:2013-08-01 09:48:05

标签: php node.js

我有一个接收应用程序,它需要来自PHP生产者的字符串,如下所示:

<?php
        $shared_secret = 'secret';
        $data = 'whatever';

        # Newline added for viewing convenience only
        echo bin2hex(mcrypt_encrypt(MCRYPT_BLOWFISH, $shared_secret, $data,
                     MCRYPT_MODE_ECB)) . "\n";

        # -> 05c3febb9970204a
?>

接收器的更换成本很高。

我正在使用node.js构建另一个生产者,我无法获取我的JavaScript代码来生成相同的输出:

  var data, encrypt, sharedSecret;

  sharedSecret = 'secret';
  data = 'whatever';

  encrypt = function(d) {
    var cipher, crypto;
    crypto = require('crypto');
    cipher = crypto.createCipher('bf-ecb', sharedSecret, '\0\0\0\0\0\0\0\0');
    cipher.update(d);
    return cipher.final('hex');
  };

  console.log(encrypt(data));

  // -> 35c9801f2afca332

我选择了'bf-ecb'密码,因为我觉得这是ECB模式下的河豚。我提供了8个空字节作为IV,因为mcrypt_encrypt的PHP文档说如果省略IV,它使用所有空字节,mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB)回答8.我选择了'hex',因为我认为它提供了与PHP'2 bin2hex()相同的表示形式。

我应该如何处理我的JavaScript代码以匹配PHP代码的输出?

1 个答案:

答案 0 :(得分:2)

我的代码只有四个问题:

  • 输出不必相同。它只需要解密到相同的明文。鉴于节点和PHP填充不同,追逐相同的密码对我来说很愚蠢。
  • ECB模式不使用IV。我误导了我的PHP mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB)报告了8而不是说“你是个傻瓜”。
  • 我输错了crypto.createCipheriv(),它使用了给定的密钥。 crypto.createCipher()使用给定密钥的推导(md5,我认为)。
  • 不得丢弃update()的返回值。

所以工作解决方案是:

  var data, encrypt, sharedSecret;

  sharedSecret = 'secret';
  data = 'whatever';

  encrypt = function(d) {
    var cipher, crypto;
    crypto = require('crypto');
    cipher = crypto.createCipheriv('bf-ecb', sharedSecret, '');
    return cipher.update(d, 'utf8', 'hex') + cipher.final('hex');
  };

  console.log(encrypt(data));