我正在接收来自外部方的加密消息。他们使用php和mcrypt
进行加密,具有以下配置
"a364cb3bb55c2788b25f04ef6867d770771a7d0fdd44462b40233ea76a8bd00d"
。其原始邮件为"thank you"
以下图像显示了配置
从我这边,我正在使用nodejs来解密。我有node-mcrypt binding的工作版本。但我想避免本机模块,所以我正在寻找一个纯粹的JavaScript解决方案。
我尝试了节点crypto
,但其aes-256-ecb
生成了不同(不可读)的输出
在nodejs中使用MCrypt绑定的工作代码:
const decryptAES256 = (encrypted: string, password: string): string => {
try {
const desEcb = new MCrypt('rijndael-256', 'ecb');
desEcb.open(md5(password));
const ciphertext = desEcb.decrypt(new Buffer(encrypted, 'hex'));
const plain = ciphertext.toString();
const isUTF8 = plain.split('').every(c => c.charCodeAt(0) <= 256);
if (!isUTF8) {
throw new Error('Invalid Input');
}
const unpadding = plain
.split('')
.filter(c => c.charCodeAt(0))
.join('');
return unpadding;
} catch (ex) {
console.error('Invalid token');
}
};
答案 0 :(得分:1)
当您声明可能指定不是AES的256位块大小的“rijndael-256”时。 AES有一个块大小:128位。
这似乎是由32位二进制字节的加密输出产生的,对于“谢谢”的输入,输出应该是一个块,因此块大小似乎是32字节(256位)。
答案 1 :(得分:0)
在意识到rijndael 256不等同于aes 256(128版本)之后,我选择在纯javascript中找到一个rijndael特定的lib,这是一个有效的代码:
const Rijndael = require('rijndael-js');
describe('cipher', () => {
it('should work', () => {
const text = 'thank you';
// + String.fromCharCode(0).repeat(5)
const key = '94a08da1fecbb6e8b46990538c7b50b2';
const cipher = new Rijndael(key, 'ecb');
const ciphertext = cipher.encrypt(text, 256);
expect(ciphertext.toString('hex')).toBe(
'a364cb3bb55c2788b25f04ef6867d770771a7d0fdd44462b40233ea76a8bd00d'
);
const plaintext = cipher.decrypt(ciphertext, 256);
const unpadded = plaintext.toString().replace(/\u0000*$/g, '');
expect(unpadded).toBe(text);
});
});