【问题标题】:Decrypting mcrypt encoded text with node.js使用 node.js 解密 mcrypt 编码的文本
【发布时间】:2012-02-12 07:13:15
【问题描述】:

我有使用 PHP 的 mcrypt 用 Blowfish 编码的文本:

$td = mcrypt_module_open ('blowfish', '', 'cfb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
mcrypt_generic_init ($td, "somekey", $iv);
$crypttext = mcrypt_generic ($td, "sometext");
mcrypt_generic_deinit ($td);
$res = base64_encode($iv.$crypttext);

当尝试使用 Node 的加密库解码数据时,我得到了垃圾输出。

var crypto = require("crypto"),
    ivAndCiphertext = "base64-encoded-ciphertext", 
    iv, cipherText, ivSize = 8, res= "";

ivAndCiphertext = new Buffer(ivAndCiphertext, 'base64');
iv = new Buffer(ivSize);
cipherText = new Buffer(ivAndCiphertext.length - ivSize);
ivAndCiphertext.copy(iv, 0, 0, ivSize);
ivAndCiphertext.copy(cipherText, 0, ivSize);

c = crypto.createDecipheriv('bf-cfb', "somekey", iv.toString("binary"));
res = c.update(cipherText, "binary", 'utf8');
res += c.final('utf8');

知道我做错了什么吗?

编辑

直接使用 openssl(加密库是其包装器)会产生相同的乱码结果:

openssl enc -K the_key_in_hex bf-cfb -d -p -iv the_iv_in_hex -nosalt -nopad -a

所以看起来 Javascript 代码没有问题。

【问题讨论】:

    标签: javascript node.js cryptography mcrypt blowfish


    【解决方案1】:

    https://github.com/tugrul/node-mcrypt

    加密:

    var mcrypt = require('mcrypt');
    
    var bfEcb = new mcrypt.MCrypt('blowfish', 'cfb');
    var iv = bfEcb.generateIv();
    
    bfEcb.open('somekey', iv);
    
    var cipherText = bfEcb.encrypt('sometext');
    
    console.log(Buffer.concat([iv, cipherText]).toString('base64'));
    

    解密:

    var mcrypt = require('mcrypt');
    var bfEcb = new mcrypt.MCrypt('blowfish', 'cfb');
    
    var ivAndCiphertext = new Buffer('AyvfjTyg24Y9fVCdjzRPEw==', 'base64');
    
    var ivSize = bfEcb.getIvSize();
    var iv = new Buffer(ivSize);
    var cipherText = new Buffer(ivAndCiphertext.length - ivSize);
    
    ivAndCiphertext.copy(iv, 0, 0, ivSize);
    ivAndCiphertext.copy(cipherText, 0, ivSize);
    
    bfEcb.open('somekey', iv);
    
    console.log(bfEcb.decrypt(cipherText).toString());
    

    【讨论】:

    • 此模块似乎不再工作或不再维护。
    【解决方案2】:

    您使用的是ivAndCiphertext = "base64-encoded-ciphertext",后跟ivAndCiphertext = new Buffer(ivAndCiphertext, 'base64');。您的变量将指向新缓冲区,因此您将获得解密新缓冲区的结果。

    【讨论】:

      【解决方案3】:

      我不确定是否还有其他错误,但是在使用 IV 时,您应该使用 createDecipheriv 方法:

      http://nodejs.org/docs/latest/api/crypto.html#crypto.createDecipheriv

      【讨论】:

      • 你是对的,复制代码时出错。修正了问题。
      • 由于密文是base64编码的,我认为你应该这样做:res = c.update(cipherText, "base64", 'utf8');
      • cipherText 是一个Buffer,当传递到update 时被解释为二进制编码字符串。
      • 对不起,我错过了你将它作为 base64 读入缓冲区。好吧,考虑到它与仅 openssl 相同,我认为我无能为力!
      猜你喜欢
      • 2015-12-31
      • 2011-01-27
      • 2013-12-28
      • 2015-10-09
      • 2012-07-27
      • 2012-06-10
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      相关资源
      最近更新 更多