Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在node.js中重新创建MCRYPT_RIJNDAEL_128_Javascript_Php_Node.js_Aes_Mcrypt - Fatal编程技术网

Javascript 在node.js中重新创建MCRYPT_RIJNDAEL_128

Javascript 在node.js中重新创建MCRYPT_RIJNDAEL_128,javascript,php,node.js,aes,mcrypt,Javascript,Php,Node.js,Aes,Mcrypt,正在尝试在node.js中重新创建以下php加密代码: $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($size, MCRYPT_RAND); $msg = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 'MY_KEY_LONG_STRING', 'PLAINTEXT', MCRYPT_MODE_ECB, $iv

正在尝试在node.js中重新创建以下php加密代码:

$size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($size, MCRYPT_RAND);
$msg = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 'MY_KEY_LONG_STRING', 'PLAINTEXT', MCRYPT_MODE_ECB, $iv));
我试过这个:

var text = 'PLAINTEXT';
var len = text.length;
for (var i = 0; i < 16 - len % 16; i++) {  // pad to multiple of block size 
    text += '\0';
}
var key = 'MY_KEY_LONG_STRING';
key = key.substr(0, 16); // trim to expected key size for aes128

var cipher = crypto.createCipher('aes-128-ecb', key);
cipher.setAutoPadding(false); // did our own padding, to match mcrypt_encrypt
var encrypted = cipher.update(text, 'utf8', 'base64');
encrypted += cipher.final('base64');

而且,与php的结果不同。有没有办法让它的行为与php版本一模一样?

两个结构相当糟糕的库相互对抗会很有趣。我不会做所有的工作,而是按照要求提供一些想法:

  • PHP并没有删除密钥字节,而是使用零填充将它们扩展到下一个可用的密钥大小——在您的情况下是192位或24字节;为此,您需要将
    aes-192-ecb
    指定为算法(您需要继续使用
    MCRYPT_RIJNDAEL_128
    ,但替换为PHP中的128是块大小而不是键大小)
  • 填充不正确,PHP填充0..15个零字节,而不是1..16字节
  • 不能使用2参数
    createCipher
    ,因为第二个参数是密码;如果使用node.js,它将执行密钥派生,因此需要使用三个参数
    createCipher
    ,并提供任意16字节的IV
PHP中的IV代码只对随机数生成器进行了不必要的征税,没有使用IV


进行填充的代码

var padSize = 16 - ((len + 16 - 1) % 16 + 1);
for (var i = 0; i < padSize; i++) {  // pad 0 .. 15 until to multiple of block size 
    text += '\0';
}
var padSize=16-((len+16-1)%16+1);
对于(var i=0;i

或者您可以使用自己的填充方法(在问题中),除非
len%16==0

以下是我的代码,用于解决从PHP迁移到NodeJS的问题。我有严格的32字节密钥,因此必须使用
aes-256-ecb

我想重写的PHP代码:

$text = "Some super mega text I want to encode";
$skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";

function encode($text,$skey) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $skey, $text, MCRYPT_MODE_ECB, $iv);
    return base64_encode($crypttext);
}

echo encode($text,$skey);
var crypto = require('crypto');

var text = "Some super mega text I want encode";
var skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";

function encode(text, skey) {
    var len = text.length;
    var padSize = 16 - ((len + 16 - 1) % 16 + 1);
    for (var i = 0; i < padSize; i++) { 
        text += '\0';
    }
    var cipher = crypto.createCipheriv('aes-256-ecb', skey, '');
    cipher.setAutoPadding(false);
    var encrypted = cipher.update(text, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    return encrypted;
}

console.log(encode(text, skey));
npm install mcrypt
输出:

dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
NodeJS:

$text = "Some super mega text I want to encode";
$skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";

function encode($text,$skey) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $skey, $text, MCRYPT_MODE_ECB, $iv);
    return base64_encode($crypttext);
}

echo encode($text,$skey);
var crypto = require('crypto');

var text = "Some super mega text I want encode";
var skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";

function encode(text, skey) {
    var len = text.length;
    var padSize = 16 - ((len + 16 - 1) % 16 + 1);
    for (var i = 0; i < padSize; i++) { 
        text += '\0';
    }
    var cipher = crypto.createCipheriv('aes-256-ecb', skey, '');
    cipher.setAutoPadding(false);
    var encrypted = cipher.update(text, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    return encrypted;
}

console.log(encode(text, skey));
npm install mcrypt
NodeJS-mcrypt包也可以工作:

$text = "Some super mega text I want to encode";
$skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";

function encode($text,$skey) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $skey, $text, MCRYPT_MODE_ECB, $iv);
    return base64_encode($crypttext);
}

echo encode($text,$skey);
var crypto = require('crypto');

var text = "Some super mega text I want encode";
var skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";

function encode(text, skey) {
    var len = text.length;
    var padSize = 16 - ((len + 16 - 1) % 16 + 1);
    for (var i = 0; i < padSize; i++) { 
        text += '\0';
    }
    var cipher = crypto.createCipheriv('aes-256-ecb', skey, '');
    cipher.setAutoPadding(false);
    var encrypted = cipher.update(text, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    return encrypted;
}

console.log(encode(text, skey));
npm install mcrypt
代码:

输出:

dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD

我尝试了其他的选择,但没有任何效果,但这对我来说是有效的

function encrypt(text) {
  text = '' + text;
  var crypto = require('crypto');
  var len = text.length;
  var padSize = 16 - (((len + 16 - 1) % 16) + 1);
  var data = String.fromCharCode(padSize);
  var text = text + data.repeat(padSize);

  var cipher = crypto.createCipheriv('aes-128-ecb','secretKey', '');
  cipher.setAutoPadding(false);
  var encrypted = cipher.update(text, 'utf8', 'base64');
  encrypted += cipher.final('base64');
  return encrypted;
}
PHP中的Similer

function aes128Encrypt($str,$key){
$block = mcrypt_get_block_size('rijndael_128', 'ecb');
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB));
}

默认免责声明:ECB是不安全的,在没有MAC的情况下传输数据更不安全(而且我对使用JavaScript和PHP进行加密也有严重的怀疑)嗨,Maarten,感谢您的想法:1)当将密钥填充到24字节并调用
crypto.createCipheriv
,node.js给出错误
节点加密:无效密钥长度24
。不过,php扩展到24字节的事实是有帮助的。2) 你说的“PHPpad0..15…”是什么意思?3) 根据注释判断,PHP中的IV代码是为了避免在早期版本的PHP中不提供IV参数时抛出的错误。@PashaBitz 1)检查我的更改答案(在第一项上)以获得24字节密钥问题的解决方案。2) PHP在达到下一个块大小之前一直使用零填充,但如果块大小已经是块大小的x倍,则不会填充。3) 至于IV,我只给它一个16字节的字节数组,初始化为所有零。如果未使用IV,则可能需要提供IV,但将其随机化没有意义。当密钥填充为24个字符时,
crypto。createCipheriv
仍会抛出错误
节点加密:无效密钥长度24
。不过,由于键被修剪为16个字符,确实会产生相同的结果,感谢您发现了填充错误!!替换为aes-192-ecb确实会产生与PHP相同的输出,具有24字节的密钥。。。不知怎的,我在你原来的帖子里漏掉了那句话。非常感谢。ECB不能使用IV,因此您的php代码可以压缩为:
$msg=base64_encode(mcrypt_RIJNDAEL_128,'MY_KEY_LONG_STRING','PLAINTEXT',mcrypt_MODE_ECB))你有解码的机会吗?