将PHP mcrypt()调用转换为节点的mcrypt [英] Converting a PHP mcrypt() call to node's mcrypt

查看:150
本文介绍了将PHP mcrypt()调用转换为节点的mcrypt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Node的mycrypt模块将旧PHP应用程序中的加密功能重新创建为新的Node JS应用程序.

I am trying to recreate an encryption function that we have in our old PHP application into a new Node JS application, using Node's mycrypt module.

我的目标是确保在给定相同的原始字符串和盐的情况下,下面的PHP脚本产生与Node脚本相同的加密值.

My goal is the make sure that given the same original string and salt, the PHP script below produces the same encrypted value as the Node script.

PHP

<?php
$string = 'This is my password';
$salt = 'sodiumChloride12';
$encrypted = base64_encode(
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        $salt,
        $string,
        MCRYPT_MODE_ECB,
        mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND)
    )
);

echo "Encrypted: $encrypted\n";

它产生:

Encrypted: iOKEAxaE4vIeWXBem01gHr2wdof7ZO2dld3BuR9l3Nw=


JavaScript

var mcrypt = require('mcrypt');
var MCrypt = mcrypt.MCrypt;

// Set algorithm and mode
var rijndaelEcb = new MCrypt('rijndael-128', 'ecb');

// Set up salt and IV
var salt = 'sodiumChloride12';
var iv = rijndaelEcb.generateIv();
rijndaelEcb.open(salt, iv);

/** ENCRYPTION **/
var cipher = rijndaelEcb.encrypt('This is my password');
var cipherConcat = Buffer.concat([iv, cipher]).toString('base64');
console.log('Encrypted: ' + cipherConcat);

/** DECRYPTION **/
// Convert back from base64
var ivAndCipherText = new Buffer(cipherConcat, 'base64');

// Undo concat of IV
var ivSize = rijndaelEcb.getIvSize();
iv = new Buffer(ivSize);
var cipherText = new Buffer(ivAndCipherText.length - ivSize);
ivAndCipherText.copy(iv, 0, 0, ivSize);
ivAndCipherText.copy(cipherText, 0, ivSize);

var plaintext = rijndaelEcb.decrypt(cipherText).toString();
console.log('Decrypted: ' + plaintext);

Node版本产生:

Encrypted: 834aJoVRxla/fGNACUAVFYjihAMWhOLyHllwXptNYB69sHaH+2TtnZXdwbkfZdzc
Decrypted: This is my password

基于它解密了原始短语的事实,我知道调用按预期进行,但是加密的输出与PHP脚本中的不同.解密逻辑来自此答案,但我更关心的是使加密以相同方式工作.

Based on the fact that it decrypted the original phrase, I know the calls are working as expected, but the encrypted output is not the same as in the PHP script. Decryption logic was from this answer, but I'm more concerned with making the encryption work the same way.

我在Node中使用IV进行的操作与PHP中有所不同吗?

Am I doing something different with the IV in Node than in PHP?

我看了

I looked at this question, but it uses the crypto module instead of the mcrypt module I am using.

推荐答案

我在Node中使用IV进行的操作与PHP中有所不同吗?

Am I doing something different with the IV in Node than in PHP?

嗯.代码怎么说?

MCRYPT_MODE_ECB,

var rijndaelEcb = new MCrypt('rijndael-128', 'ecb');

您使用的是 ECB模式,该模式不使用IV.您实际上是在浪费CPU周期来生成一个周期.即使您使用的是CBC模式,MCRYPT_RAND也是在此处无法使用的常量.

You're using ECB mode, which doesn't use an IV. You're actually wasting CPU cycles generating one. Even if you were using CBC mode, MCRYPT_RAND is a bad constant to use here.

var cipherConcat = Buffer.concat([iv, cipher]).toString('base64');

您要将未使用的IV连接到您的密文,并抱怨结果无效? PHP代码仅返回cipher(用等效于Node.js的术语),而不是ivcipher的串联.

You're concatenating an unused IV to your ciphertext, and complaining about an invalid result? The PHP code just returns cipher (in Node.js equivalent terms), not a concatenation of iv and cipher.

更重要的是,从上述的ECB模式开始,这里需要解决一些严重的密码学缺陷:

More importantly, there are some serious cryptography flaws here that need to be addressed, starting with ECB mode as mentioned above:

  1. 请勿加密密码,请使用密码哈希算法. 有很大的区别.. li>
  2. 如果您要加密,请使用经过身份验证的加密.
  3. 不要使用mcrypt .
  4. 不要将自家的加密协议部署到生产或鼓励其他开发人员也这样做.
  1. Do not encrypt passwords, use a password hashing algorithm. There's a huge difference.
  2. If you're going to encrypt, use authenticated encryption.
  3. Don't use mcrypt.
  4. Don't deploy home-grown crypto protocols into production or encourage other developers to do the same.

推荐步骤:

  1. 使用PHP解密数据,然后存储密码正确.
  2. 如果您出于其他任何目的需要加密,请使用高级加密库,如libsodium.
  1. Decrypt your data with PHP, then store passwords properly.
  2. If you need encryption for any other purpose, use a high-level cryptography library, like libsodium.

这篇关于将PHP mcrypt()调用转换为节点的mcrypt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆