首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将PHP mcrypt()调用转换为节点的mcrypt

将PHP mcrypt()调用转换为节点的mcrypt
EN

Stack Overflow用户
提问于 2016-05-18 02:16:34
回答 1查看 871关注 0票数 0

我正在尝试使用Node的mycrypt模块将我们在旧PHP应用程序中的加密功能重新创建到一个新的Node应用程序中。

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

代码语言:javascript
复制
<?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";

它产生:

代码语言:javascript
复制
Encrypted: iOKEAxaE4vIeWXBem01gHr2wdof7ZO2dld3BuR9l3Nw=

JavaScript

代码语言: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版本产生:

代码语言:javascript
复制
Encrypted: 834aJoVRxla/fGNACUAVFYjihAMWhOLyHllwXptNYB69sHaH+2TtnZXdwbkfZdzc
Decrypted: This is my password

基于对原始短语进行解密的事实,我知道调用按预期工作,但加密的输出与PHP脚本中的输出不一样。解密逻辑来自这个答案,但我更关心的是如何使加密以同样的方式工作。

我在Node中对IV所做的事情与PHP中的不同吗?

我看过这个问题,但它使用的是crypto模块,而不是我正在使用的mcrypt模块。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-18 15:08:34

我在Node中对IV所做的事情与PHP中的不同吗?

嗯。密码是怎么说的?

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

您使用的是欧洲央行模式,它不使用IV,实际上是在浪费CPU周期来生成IV。即使您使用的是CBC模式,在这里使用MCRYPT_RAND也是一个糟糕的常量。

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

您正在将一个未使用的IV连接到您的密文,并抱怨无效的结果?PHP代码只返回cipher (用Node.js等效的术语),而不是ivcipher的连接。

更重要的是,这里有一些严重的密码缺陷需要解决,首先是欧洲央行模式,如上文所述:

  1. 不要加密密码,使用密码哈希算法。有一个很大的区别
  2. 如果你要加密,使用认证加密
  3. 不要使用mcrypt
  4. 不要将本地开发的密码协议部署到产品中,或者鼓励其他开发人员这样做。

建议的步骤:

  1. 用PHP解密数据,然后存储密码适当地
  2. 如果您需要任何其他用途的加密,使用高级密码库,如like。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37289128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档