使用 nodejs crypto 与 php 的 mcrypt 解密 Blowfish-ecb
Posted
技术标签:
【中文标题】使用 nodejs crypto 与 php 的 mcrypt 解密 Blowfish-ecb【英文标题】:Decrypting blowfish-ecb with nodejs crypto vs php's mcrypt 【发布时间】:2012-01-28 16:24:27 【问题描述】:我正在尝试使用内置加密库在 Node.js 中解码以下 base64 编码的密文
2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==
它似乎可以使用字符串 typeconfig.sys^_-
作为键与 php 的 mcrypt 函数一起使用,如将值输入到 http://www.tools4noobs.com/online_tools/decrypt/ 并选择 Blowfish、ECB、Base64 解码所示。
但是,当我在 Node.js 中运行以下代码时:
var crypto = require('crypto');
var data = "2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==";
var decipher = crypto.createDecipher('bf-ecb', 'typeconfig.sys^_-');
data = decipher.update(data, "base64", "utf8");
data += decipher.final("utf8");
console.log(data);
我得到垃圾输出:
y
�:����d�(����Q�i��z1��4�� �k�(� ��a5����u��73c/��(ֻ��)��������fȠ���
�ec�-<z�8����(�-L���ԛ�I��1L*��u�4�j-�Чh쭊@\P)?�.�^���q㊬�U���W&�x��85�T-ג9,dE<g�`*�
��|@����k"�!�D'u���,x��7����
��9q=q�q��ա>�w�T����H3͜�i)R��zy��C��
��o�
我还尝试了对库本身的测试,因为它似乎能够很好地处理它自己编码的东西:
var crypto = require('crypto')
var cipher = crypto.createCipher("bf-ecb", "key");
var data = cipher.update("foobar", "utf8", "base64");
data += cipher.final("base64");
console.log(data);
var decipher = crypto.createDecipher("bf-ecb", "key");
data = decipher.update(data, "base64", "utf8");
data += decipher.final("utf8");
console.log(data);
产生:
y0rq5pYkiU0=
foobar
但复制并粘贴该 base64 字符串并将其输入到 http://www.tools4noobs.com/online_tools/decrypt/ 旁边的键“key”也会产生垃圾输出。
这两个库不应该产生相同的输出,还是我做错了什么?
【问题讨论】:
Node.js 和 PHP 的 mcrypt 的文档不清楚,但看起来 Node.js 使用了密钥派生函数,而 mcrypt 使用的是原样的密钥。由于 Node.js 实现了 PBKDF2,我猜这是它的密钥派生算法,但我不知道如何指定参数。您应该弄清楚它使用的参数,然后根据您的密码派生一个密钥,并在 PHP 端使用该密钥。 哦,另外,我注意到在工作的 Node.js 代码中,您使用createCipher()
来加密 和 解密,而在您原来的、不工作的代码中,您正在使用createDecipher()
。
@erickson 是的,createCipher
两次是拼写错误,抱歉.. 我的问题是我正在尝试与需要该特定原始密钥的另一个服务兼容(请参阅第一个 base64 编码例如字符串),所以你的回答帮助解释了两者之间的区别,它实际上并不能帮助我解码和编码我需要的东西。
【参考方案1】:
Node.js 在将密码用作密钥之前计算密码的 MD5 哈希值。据我所知,mcrypt 按原样使用密钥。
计算密码的 MD5 哈希值,并将其用作 mcrypt 密钥。
【讨论】:
这似乎足以推动正确的方向。createCipher
和 createDecipher
使用密钥的 MD5 哈希,而 createCipheriv
和 createDecipheriv
使用原始密钥和提供的 IV。更改代码以使用 crypto.createDecipheriv('bf-ecb', 'typeconfig.sys^_-', '')
使其现在可以工作。谢谢!
@erickson 对这个问题有什么想法吗? ***.com/questions/37825261/…【参考方案2】:
https://github.com/tugrul/node-mcrypt
var mcrypt = require('mcrypt');
var bfEcb = new mcrypt.MCrypt('blowfish', 'ecb');
bfEcb.open('typeconfig.sys^_-');
var cipherText = new Buffer('2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==', 'base64');
console.log(bfEcb.decrypt(cipherText).toString());
bfEcb.close();
【讨论】:
以上是关于使用 nodejs crypto 与 php 的 mcrypt 解密 Blowfish-ecb的主要内容,如果未能解决你的问题,请参考以下文章
比较用 PHP hash() 和 NodeJS crypto.createHash() 制作的 SHA256