Я пытаюсь перенести этот рабочий php-код в Node.js, но я получаю Error: Invalid IV length 32
Вот код PHP:
//--- PHP example code (works): --- $aes_iv = 'MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ%3D'; $payload = base64_decode($payload); $aes_iv = base64_decode($aes_iv); // secret key. 64 character hex string: $shared_key = '14370ced836 ...'; // convert from hex to binary string: $shared_key = pack('H*', $shared_key); // AES decrypt payload $payload = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $shared_key, $payload, MCRYPT_MODE_CBC, $aes_iv); // AES adds null characters to the end of short strings, // so we should strip them out $payload = rtrim($tp_payload, "\0");
Вот код Node.js, который не работает. См. «Ошибка: недопустимая длина IV 32»
//--- Node.js equivalent ??? --- var aes_iv = 'MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ%3D'; var payload_s = new Buffer(payload, 'base64').toString(); var aes_iv_s = new Buffer(aes_iv, 'base64').toString(); // secret key. 64 character hex string: var shared_key = '14370ced836 ...'; // convert from hex to binary string: var shared_key_b = new Buffer(shared_key, 'hex').toString('binary'); // Error: Invalid IV length 32 var decipher = crypto.createDecipheriv('aes-256-cbc', shared_key_b, aes_iv_s); var decoded = decipher.update(payload_s); decoded += decipher.final(); console.log(decoded);
MCRYPT_RIJNDAEL_256
относится к алгоритму шифрования rijndael с размером нестандартного блока размером 256
бит, а не размером ключа в 256
бит. PHP использует libmcrypt
для своего шифрования, тогда как Node.js использует openssl
, а в то время как libmcrypt реализует AES (размер блока 128 бит), он также реализует rijndael с настраиваемым размером блока.
AES определенно определен с размером блока 128 бит, и это единственная версия поддержки rijndael openssl. Таким образом, я написал минимальную привязку libmcrypt для узла node-rijndael , который должен служить вашим целям. См. Также мой ответ на аналогичный вопрос здесь .
var Rijndael = require('node-rijndael'); // shared_key var key = '14370ced836...'; // aes_iv var iv = new Buffer('MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ=', 'base64'); var payload = new Buffer(/*payload*/); var rijndael = new Rijndael(key, { mode: Rijndael.MCRYPT_MODE_CBC, encoding: 'hex', // shared_key encoding iv: iv }); // defaults to utf-8 output encoding payload = rijndael.decrypt(payload); payload = payload.replace(/\0+$/, '');
Попробуйте что-то подобное для node.js:
var aes_iv_b = new Buffer(aes_iv, 'base64'), shared_key_b = new Buffer(shared_key, 'hex'), decipher = crypto.createDecipheriv('aes-256-cbc', shared_key_b, aes_iv_b), decoded = Buffer.concat([ decipher.update(payload, 'base64'), decipher.final() ]); // if the output is utf8/ascii you might be able to improve performance by using // something like this instead: // decoded = decipher.update(payload, 'base64', 'utf8') // or 'ascii' // + decipher.final('utf8'); // or 'ascii' console.log(decoded);
Если вы можете изменить PHP-код, чтобы использовать openssl
с aes-256-cbc
вместо libmcrypt
, тогда вы можете использовать стандартную crypto
библиотеку, как я использовал в этом другом ответе
Надеюсь, поможет. С уважением, Игнасио