node.js - nodejs crypto 是否有加密和解密文本,每次都应该给出不同的加密

标签 node.js encryption aes cryptojs

我知道带有缓冲区的 AES 256 CBC 可以提供不同的加密,但其长度66。 这是我的代码

  const crypto = require('crypto');
  const ENCRYPTION_KEY = 'Must256bytes(32characters)secret';
  const IV_LENGTH = 16;
  function encrypt(text) {
    let iv = crypto.randomBytes(IV_LENGTH);
    let cipher = crypto.createCipheriv('aes-256-cbc', new Buffer(ENCRYPTION_KEY), iv);
    let encrypted = cipher.update(text.toString());
    encrypted = Buffer.concat([encrypted, cipher.final()]);
    return iv.toString('hex') + 'XX' + encrypted.toString('hex');
  }
  function decrypt(text) {
    let textParts = text.split('XX');
    let iv = new Buffer(textParts.shift(), 'hex');
    let encryptedText = new Buffer(textParts.join('XX'), 'hex');
    let decipher = crypto.createDecipheriv('aes-256-cbc', new Buffer(ENCRYPTION_KEY), iv);
    let decrypted = decipher.update(encryptedText);
    try{
      decrypted = Buffer.concat([decrypted, decipher.final()]);
      return decrypted.toString();
    }catch(Err){
      return 'NULL';
    }
  }

问题是加密数据长度为 66,即使文本为 1
那么是否有任何加密和解密方法应该每次给出不同的加密数据,并且文本为 1 时少于 10 个字符(根据我的示例)

谢谢

最佳答案

是的。您可以获得 5 个字节(或 10 个十六进制字符)或更少的密文。但如此短的密文是有问题的。

基本上有两种方法。我将从更简单的开始。

计数器模式(CTR)

您可以将 CTR(计数器)模式与随机数一起使用。使用 CTR 模式加密 X 字节会得到恰好 X 字节的结果。 CTR模式不需要将明文填充到 block 大小的N倍。

此随机数(使用过一次的数字)必须是唯一的数字,否则您的明文将面临暴露的直接危险。你不能仅仅依赖一个随机数;由于生日限制,4 字节随机数具有很高的重复概率。

因此,您要么需要单独存储随机数,要么在密文中包含 4 字节随机数。然而,如果你设法重复使用随机数,那么你就完蛋了。对于如此少量的字节,这意味着您基本上必须保留一个 4 字节计数器,这意味着必须存储状态

通常,CTR 模式加密例程要求您提供 IV 而不是随机数。这只是初始计数器值。您必须通过获取随机数来构造该值,然后用零值字节对其进行右填充,直到达到 16 字节(AES 的 block 大小)。

您可以找到示例代码here ,别忘了点赞哦。 Rob 还提供了一些示例代码 in his answer .

格式保留加密(FPE)

通过格式保留加密,加密的输出使用精确的位数或什至值作为输入的可能值。听起来不错,但 FPE 由一堆相对复杂的算法组成。基本上你必须在 JavaScript 中找到一个加密库来实现它。

请注意,使用 FPE,相同的消息将始终加密为相同的密文。根据应用程序的不同,这可能是也可能不是问题。

<小时/>

注释:

  • 您使用的是十六进制编码,这不是最密集的编码,您可以使用 Base 64 甚至 ASCII 85 编码。
  • 首先将 IV 和密文连接为字节然后执行编码会更有效。如果 IV 的大小是静态的,则可以简单地使用常量而不是分隔符。
  • 您的 key 应由随机字节组成,而不是文本字符串。密码需要使用密码哈希进行转换。

关于node.js - nodejs crypto 是否有加密和解密文本,每次都应该给出不同的加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50307269/

相关文章:

objective-c - AES256EncryptWithKey 方法的 openssl 等效项

javascript - 类型 'Server' 上不存在属性 'typeof "http"'

linux - 加密/解密在两个不同的 openssl 版本之间不能很好地工作

java - 如何在 Java 中为 AES 算法创建自己的 key ?

c# - 对大文件使用 Rijndael 加密

Azure 磁盘加密与主机加密

encryption - AES CTR 测试向量

node.js - 如何在bluemix上配置socket.io粘性 session

mysql - 在 MySQL Loopback Connector 上执行原始查询

node.js - Node.js 是否支持并行性?