按照OpenSSL的建议正确实现密钥派生,用于“Crypto”库(nodejs)

时间:2017-10-03 08:57:11

标签: node.js encryption cryptography pbkdf2

我正在修复issue。阅读这个问题会让你更好地了解这个问题,尽管如此我在这里用我自己的语言写这个问题。

  

系统应该如何运作:

     

用户输入textpassword,它会在强加密后保存在文件中。当用户输入encryptedTextpassword时,它会返回解密的文本。目前,使用Crypto node.js库处理加密,函数使用createCipher

问题:该解决方案与createCipher的效果非常好,但它不使用任何类型的salt机制。 Openssl建议使用pbkdf2来获取密钥。我理解为什么有必要,因为否则文本的加密值总是相同的(例如,使用相同密码的“1234”加密将始终导致“xyz”),这使得彩虹表攻击变得容易/可能。

解决方案我正在尝试:我开始实施Openssl的建议,使用pbkdf2来获得密钥派生机制,但我不太清楚如何正确地完成它。请帮助我理解并找出解决此问题的正确方法。我正在考虑采用以下方法,但很多事情似乎都缺失了

  1. deriveKey(password):使用随机盐和任何哈希算法(“sha256”可能)为密码字符串创建哈希值,迭代次数= 64000.
    derivedKey = crypto.pbkdf2Sync(password, salt=crypto.randomBytes(256), iterations, 512, 'sha256',...)

  2. encrypt(text, derivedKey, cb)

    • 使用cipherObject创建derivedKey
      cipherObject = createCipheriv(algo="aes-256-cbc", derivedKey, iv2=randomBytes(256),...)
    • 应用加密:
      cipherText = cipherObject.update(text,...)
    • 存储encryptedText
      1:salt;iters:IV:cipherText在本地文件中(感谢@bartonjs让我理解这一点)
  3. decrypt(encryptedText, password): 所以要解密的文本如下所示:1:salt;iters:IV:cipherText
    • 从保存的配置中获取:
      derivedKey = pbkdf2Sync(password, salt, iters, 'sha256')
    • 使用相同算法和以上derivedKey创建解密对象:decipherObject = createDecipherIv("aes-256-cbc", derivedKey, IV...)
    • 更新decipherObject以获得最终的原始文本:
      text = decipherObject.update(cipherText,...)
  4. 我按优先顺序排列的三大问题

    1. 我在概念上做得对吗?
    2. 我是否需要考虑安全问题?
    3. 我是否遵循最佳做法?有什么可以改进的。
    4. P.S。我不是加密专家,有助于从一个

      获得意见

2 个答案:

答案 0 :(得分:0)

  

对于解密,我想我必须用iv来保存derivedKey的盐。我不知道这是否会危及安全。应该是什么解决方案?

来自NIST glossary

salt
  

加密过程中使用的非秘密值,通常为   确保攻击者无法重用一个实例的计算结果。

     

消息来源:SP 800-63; CNSSI-4009

由于它被定义为“非秘密”值,因此将其写入IV旁边不会危及安全性。

请注意,您还应该为PBKDF2编写迭代计数。

salt;iters:IV:cipherText

(以冒号分隔的“Startup”,“IV”,“ciphertext”,并且通过分号将启动分解为“salt”和“迭代计数”,因此随着结构的发展,解析不会模糊。为了获得最佳结果,开头的某些内容将是“架构值”,如数字1,适用于文件格式的v1,如1:salt;iters:IV:cipherText)。

答案 1 :(得分:0)

我假设您不想自己实施,如果您不需要。正如CodeCaster所说,如果你对它没有扎实的了解,你真的不应该是实现它的人。

我的建议是使用Stanford Javascript Encryption Library (sjcl)has support for pbkdf2

查看他们的演示页面,它允许您使用密码和随机盐加密消息:

https://bitwiseshiftleft.github.io/sjcl/demo/

这里是演示源的链接,它可以让您了解如何使用它们的库实现它: https://github.com/bitwiseshiftleft/sjcl/blob/master/demo/example.js

编辑(从评论到答案)正如josh3736在评论中指出的那样,不需要第三方库。 Node的加密模块本身支持pbkdf2。他提供了以下链接作为示例: https://cafedev.org/article/2016/06/secure-text-encryption-with-nodejs/