1

我有一个接收应用程序,它需要一个来自 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 代码的输出?

4

1 回答 1

2

我的代码只有四个问题:

  • 输出不需要相同。它只需要解密成相同的明文。鉴于该节点和 PHP 垫不同,追逐相同的密码对我来说很愚蠢。
  • ECB 模式不使用 IV。我误导了我的 PHPmcrypt_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));
于 2013-08-01T11:44:37.613 回答