node.js - 如何在不增加太多大小的情况下使用 crypto 加密文本?

标签 node.js encryption cryptography

我正在像这样加密文本(node.js):

var text = "holds a long string..."
var cipher = crypto.createCipher("aes128", "somepassword")
var crypted = cipher.update(text, 'utf8', 'hex')
crypted += cipher.final('hex');

如果我直接把text存到一个文件里,就是N个字节。如果我保存 crypted,文件大小约为 N * 2 字节。

有什么方法可以使密文尽可能接近N字节?

最佳答案

像 AES 这样的现代密码适用于二进制数据。当您加密字符数据时,它首先被转换为二进制表示。这基本上就是 UTF-8 编码的作用。加密后,您会得到任意二进制数据,当您尝试对其进行解码时,它不一定是有效的 UTF-8 编码(几乎所有编码都有特殊结构)。

如果您从 Cipher#updateCipher#final 中省略了 output_encoding,您将得到一个 Buffer,您可以将其连接或写入文件。它以二进制格式管理数据,但打印时默认为十六进制。当您将缓冲区写入文件时,文件大小将接近明文大小,但永远达不到。

AES 是一种 block 密码,只能加密恰好 16 字节的单个 block 。 ECB 或 CBC 等操作模式使您能够加密多个 block 。最后,像默认 PKCS#7 填充这样的填充方案使您能够加密任意长度的文本。此填充总是在实际解密之前添加一些字节。准确地说,它增加了 1 到 16 个字节。

您可以使用 cipher.setAutoPadding(false) 来防止填充,但是您需要自己填充。您也可以使用像 CTR(“aes-128-ctr”)这样的流模式,但是您需要为其提供 12 字节的唯一 IV(随机数)有什么保障。这个 nonce 不必是 secret 的,但你必须将它传输到解密器。

最后密文真的不可能和明文大小完全一样。总有一些东西会膨胀密文。


切勿使用 crypto.createCipher。您需要使用随机 密码来获得语义安全。使用带有新鲜随机 IV 的 crypto.createCipheriv。对于 CTR 模式,IV 必须是唯一的,对于 CBC 模式,它必须是不可预测的。

始终使用经过身份验证的加密。它使您能够检测错误的 key 和(恶意的)密文篡改。 Here's AES-GCM 示例。

关于node.js - 如何在不增加太多大小的情况下使用 crypto 加密文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34872151/

相关文章:

javascript - 在 Express 项目中使用 ES6/标签时出现语法错误/转换错误

node.js - 不同环境的package.json?

javascript - 使用uzz.js 播放一个又一个声音

java - 如何在 Spring 中加密文档或限制具有特定角色的用户的访问

php - 在 Symfony php 中手动加密用户密码

objective-c - 我的 PBKDF2 实现不断得到错误的值

mysql - 如何正确处理 node-mysql 连接池中的连接持久性事物

algorithm - 需要加密和完整性吗?

unit-testing - Diffie-Hellman 检验向量

c++ - φ(n) = (p-1)(q-1) p 和 q 是两个大数找到 e 使得 gcd(e,φ(n)) = 1