我正在构建一个应用程序,其中在客户端使用密码来加密椭圆曲线 key 对的私钥。然后密码被 bcrypted 并发送到服务器(连同加密的私钥)和公钥。
最初,我在加密私钥之前使用 pbkdf2 来散列密码,但由于我也在对密码进行 bcrypting,我可以使用 bcrypted 吗?
根据 https://medium.com/@mpreziuso/password-hashing-pbkdf2-scrypt-bcrypt-1ef4bb9c19b3#.sj4jcbynx答案不仅是肯定的,而且 bcrypt 甚至更好,因为它具有更强的 GPU-ASIC 弹性。我缺少什么吗?
最佳答案
您不应该使用 bcrypt 散列输出作为加密 key ;它并不意味着成为关键 Material :
您有一个椭圆曲线私钥,要使用用户密码对其进行加密。当然你不想直接使用密码——你想使用密码到派生 一个加密 key 。为此,您可以使用:
这些都是 key 派生函数(例如基于密码的 key 派生函数)。它们的目的是在给定密码的情况下生成加密 key 。它们被设计成“硬”的。
您提供这两种算法:
它会返回一个 256 位的 key ,您可以将其用作 AES-256 的加密 key 。
然后您要备份用户的 key
我猜你然后想要:
你的问题是:既然你已经通过“散列函数”运行了他们的密码,你不能只使用那个散列作为他们存储的密码吗?
不!该散列也是保护其私钥的加密 key 。您不希望该私钥在任何地方传输。你不希望它存在于任何地方。完成后应立即从内存中删除该 32 字节加密 key 。
如果您还希望存储用户密码的哈希值,您应该做的是使用通常用于密码存储的算法:
您应该通过这些密码存储算法之一单独运行用户的密码。如果您有权访问 bcrypt;在 pbkdf2 上使用它。如果您有 scrypt,请将其用于两者:
您系统的安全性来自(除了密码的保密性)用户密码与保护其私钥的加密 key 之间的计算距离:
"hunter2" --PBKDF2--> Key material
"hunter2" ---------bcrypt-------> Key material
"hunter2" ----------------scrypt----------> Key material
您希望密码和 key 之间的距离尽可能远。
不推荐作弊
如果您真的很想节省 CPU 周期(并避免计算 scrypt 两次),那么从技术上讲,您可以采用:
Key Material ---SHA2---> "hashed password"
并将加密 key 的哈希称为您的“哈希密码”并存储它。单个 SHA2 的计算可以忽略不计。这是可以接受的,因为攻击者可以使用它的唯一方法是尝试猜测每个可能的 256 位加密 key ——这是他们首先无法解决的问题。没有办法对 256 位 key 进行暴力破解。如果他们试图对其进行暴力破解,额外的散列版本对他们没有帮助,因为他们只能通过尝试解密私钥来测试他们的尝试。
但它不太可取,因为您正在存储(转换后的)加密 key 版本。您希望尽可能少地存储该 key (以及它的任何转换版本)。
总结
并上传
关于encryption - bcrypt vs pbkdf2 用于加密私钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40566966/