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

Jun*_*ior 2 javascript php encryption rijndael node.js

我有一条消息,使用PHP加密,然后存储在MySQL数据库中.

我需要能够使用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)
Run Code Online (Sandbox Code Playgroud)

这就是我尝试使用加密模块来描述消息的方法

var crypto = require('crypto');
var encryptedText = new Buffer(rows[0]['password'], 'base64');
var decipher = crypto.createDecipheriv('sha256', 'The encryption password', 32);
var decrypted = decipher.update(encryptedText, 'hex', 'utf8') + decipher.final('utf8');

console.log('My Pass: ' + decrypted);
Run Code Online (Sandbox Code Playgroud)

这是我使用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));
}
Run Code Online (Sandbox Code Playgroud)

这就是我用PHP解密消息的方法

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));
}
Run Code Online (Sandbox Code Playgroud)

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

Art*_* B. 6

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

您需要找到支持Rijndael-256的模块.mcryptnode-rijndael会想到哪些都是libmcrypt的简单包装器,你需要另外安装它们.

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

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


安全考虑:

  • 当你导出一个键时,你应该使用随机盐和多次迭代来实现.使用PBKDF2,bcrypt或scrypt.如果密码很短(少于20个字符),那么很容易暴力破解.

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

  • 不要使用ECB模式.它在语义上不安全.至少使用带有随机初始化向量(IV)的CBC模式.IV不必是秘密的,所以只需将其添加到密文中.

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