Javascript 如何解密node.js中使用Rijndael-256加密的消息?

Javascript 如何解密node.js中使用Rijndael-256加密的消息?,javascript,php,node.js,encryption,rijndael,Javascript,Php,Node.js,Encryption,Rijndael,我有一条消息,在存储到MySQL数据库之前,它是用PHP加密的 我需要能够使用node.js/javascript破译此消息 在研究如何做到这一点时,我偶然发现了这个模块。我试图使用它,但遇到以下错误 C:\Program Files\nodejs\node_modules\mysql\lib\protocol\Parser.js:82 throw err; ^ TypeError: Not a buffer at TypeError (nat

我有一条消息,在存储到MySQL数据库之前,它是用PHP加密的

我需要能够使用node.js/javascript破译此消息

在研究如何做到这一点时,我偶然发现了这个模块。我试图使用它,但遇到以下错误

C:\Program Files\nodejs\node_modules\mysql\lib\protocol\Parser.js:82
        throw err;
              ^
TypeError: Not a buffer
    at TypeError (native)
    at new Decipheriv (crypto.js:282:16)
    at Object.Decipheriv (crypto.js:279:12)
    at Query.<anonymous> (C:\Program Files\nodejs\modules\validator.js:76:27)
    at Query._callback (C:\Program Files\nodejs\modules\dbconnect.js:46:14)
    at Query.Sequence.end (C:\Program Files\nodejs\node_modules\mysql\lib\protoc
ol\sequences\Sequence.js:96:24)
    at Query._handleFinalResultPacket (C:\Program Files\nodejs\node_modules\mysq
l\lib\protocol\sequences\Query.js:144:8)
    at Query.EofPacket (C:\Program Files\nodejs\node_modules\mysql\lib\protocol\
sequences\Query.js:128:8)
    at Protocol._parsePacket (C:\Program Files\nodejs\node_modules\mysql\lib\pro
tocol\Protocol.js:274:23)
    at Parser.write (C:\Program Files\nodejs\node_modules\mysql\lib\protocol\Par
ser.js:77:12)
这就是我使用PHP加密消息的方式

define('PHP_HASH_ALGORITHIM','sha256');
define('PHP_MCRYPT_CIPHERNAME','rijndael-256');
define('PHP_MCRYPT_MODE','ecb');
define('PHP_MCRYPT_KEY','The encryption password');

function encrypt($input, $textkey = PHP_MCRYPT_KEY) {
    $securekey = hash(PHP_HASH_ALGORITHIM, $textkey, TRUE);
    $iv = mcrypt_create_iv(32);
    return base64_encode(mcrypt_encrypt(PHP_MCRYPT_CIPHERNAME, $securekey, $input, PHP_MCRYPT_MODE, $iv));
}
function decrypt($input, $textkey = PHP_MCRYPT_KEY) {
    $securekey = hash(PHP_HASH_ALGORITHIM, $textkey, TRUE);
    $iv = mcrypt_create_iv(32);
    return trim(mcrypt_decrypt(PHP_MCRYPT_CIPHERNAME, $securekey, base64_decode($input), PHP_MCRYPT_MODE, $iv));
}
这就是我使用PHP解密消息的方式

define('PHP_HASH_ALGORITHIM','sha256');
define('PHP_MCRYPT_CIPHERNAME','rijndael-256');
define('PHP_MCRYPT_MODE','ecb');
define('PHP_MCRYPT_KEY','The encryption password');

function encrypt($input, $textkey = PHP_MCRYPT_KEY) {
    $securekey = hash(PHP_HASH_ALGORITHIM, $textkey, TRUE);
    $iv = mcrypt_create_iv(32);
    return base64_encode(mcrypt_encrypt(PHP_MCRYPT_CIPHERNAME, $securekey, $input, PHP_MCRYPT_MODE, $iv));
}
function decrypt($input, $textkey = PHP_MCRYPT_KEY) {
    $securekey = hash(PHP_HASH_ALGORITHIM, $textkey, TRUE);
    $iv = mcrypt_create_iv(32);
    return trim(mcrypt_decrypt(PHP_MCRYPT_CIPHERNAME, $securekey, base64_decode($input), PHP_MCRYPT_MODE, $iv));
}

如何使用加密正确解密消息?

在PHP中,您使用的Rijndael块大小为256位(“Rijndael-256”),密钥大小为256位(通过SHA-256输出确定)。Rijndael还支持128和192位的块大小。js的加密模块只支持AES,它与Rijndael相同,具有128位的固定块大小和可变密钥大小(128、192或256位)。这意味着您无法使用Node.js的加密模块重新创建相同的功能

您需要找到一个支持Rijndael-256的模块。请记住,哪两个都是围绕libmcrypt的简单包装器,您需要另外安装它们

如果您可以将PHP代码更改为使用AES(rijndael-128),可能会更容易

请记住,SHA-256是一个散列函数,而不是加密算法。您需要使用而不是
crypto.createDecipheriv()
从密码派生密钥


安全考虑:
  • 当您派生一个键时,您应该使用随机salt和多次迭代来实现这一点。使用PBKDF2、bcrypt或scrypt。如果密码很短(少于20个字符),那么很容易使用暴力

  • 不要使用MCrypt。这是一件废品。PHP和Node.js都支持OpenSSL加密,这使得查找兼容密码更加容易。(仍然需要选择相同的操作和填充模式。)

  • 不要使用ECB模式。它在语义上不安全。至少将CBC模式与随机初始化向量(IV)一起使用。IV不必是秘密的,所以只需在密文前加上它即可

  • 使用加密然后MAC方案和强MAC(如HMAC-SHA256)或使用经验证的操作模式(如GCM或EAX)验证密文


@BurninLeo哪里可以找到crypto.js文件?当我将iv值从32更改为这个
var iv=new Buffer(32,'binary')我收到这个错误
错误:未知密码
我不确定是否应该在那里传递数字32对不起,我误读了错误消息。根据“key和iv必须是‘二进制’编码的字符串或缓冲区。”-也就是说,在我看来,
32
是完全无效的。@artjimB非常感谢您的回答。我想尝试节点rijmdael,但正如您所说,我需要先安装libmcrypt。我没有看到npm的
libmcrypt
库。我如何安装它呢?它是一个linux甚至windows的本机库,但我对此表示怀疑。也许有Rijndael的纯JavaScript实现,但我不知道任何实现。节点是否有
libmcrypt
应该无关紧要。@ScottArciszewski为了安装库,我必须安装
libmcrypt
,但我不知道如何使用它?我正在windows上运行Node.js。@MikeA您只需编写一个最小的PHP脚本即可,并通过child_进程从Node.js调用该PHP脚本。