由于某些奇怪的原因,Node的内置Cipher
和Decipher
类无法按预期工作。 documentation指出cipher.update
“返回加密的内容,并且在流传输新数据时可以多次调用它。”
docs还指出cipher.final
“返回所有剩余的加密内容。”
但是,在我的测试中,必须调用cipher.final
来获取所有数据,从而使Cipher对象变得一文不值,并且要处理下一个块,就必须创建一个新的Cipher对象。
var secret = crypto.randomBytes(16)
, source = crypto.randomBytes(8)
, cipher = crypto.createCipher("aes128", secret)
, decipher = crypto.createDecipher("aes128", secret);
var step = cipher.update(source);
var end = decipher.update(step);
assert.strictEqual(source.toString('binary'), end); // should not fail, but does
请注意,使用秘密作为初始化向量使用
crypto.createCipher
或crypto.createCipheriv
时,会发生这种情况。解决方法是将第6和7行替换为以下内容:var step = cipher.update(source) + cipher.final();
var end = decipher.update(step) + decipher.final();
但是,如前所述,这使得
cipher
和decipher
毫无价值。这就是我希望Node的内置加密能够起作用的方式,但是显然没有。这是我使用方式上的问题还是Node中的错误?还是我期待错了事?我可以直接实现AES,但这将既耗时又烦人。每次需要加密或解密时,是否应该只创建一个新的
Cipher
或Decipher
对象?如果我将其作为流的一部分来执行,那似乎很昂贵。 最佳答案
我遇到两个问题:第一个是我错误地假设一个块的大小将是64位或8个字节,这就是我用来创建“纯文本”的内容。实际上,AES的内部结构将128位纯文本分为两个64位块,然后从那里开始。
第二个问题是,尽管在应用上述更改之后使用了正确的块大小,但crypto
模块仍在应用自动填充,并且禁用自动填充解决了第二个问题。因此,工作示例如下:
var secret = crypto.randomBytes(16)
, source = crypto.randomBytes(16)
, cipher = crypto.createCipheriv("aes128", secret, secret); // or createCipher
, decipher = crypto.createDecipheriv("aes128", secret, secret);
cipher.setAutoPadding(false);
decipher.setAutoPadding(false);
var step = cipher.update(source);
var end = decipher.update(step);
assert.strictEqual(source.toString('binary'), end); // does not fail
关于node.js - Node.js加密AES密码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12067051/