encryption - bcrypt vs pbkdf2 用于加密私钥

标签 encryption cryptography bcrypt pbkdf2

我正在构建一个应用程序,其中在客户端使用密码来加密椭圆曲线 key 对的私钥。然后密码被 bcrypted 并发送到服务器(连同加密的私钥)和公钥。

最初,我在加密私钥之前使用 pbkdf2 来散列密码,但由于我也在对密码进行 bcrypting,我可以使用 bcrypted 吗?

根据 https://medium.com/@mpreziuso/password-hashing-pbkdf2-scrypt-bcrypt-1ef4bb9c19b3#.sj4jcbynx答案不仅是肯定的,而且 bcrypt 甚至更好,因为它具有更强的 GPU-ASIC 弹性。我缺少什么吗?

最佳答案

您不应该使用 bcrypt 散列输出作为加密 key ;它并不意味着成为关键 Material :

  • BCrypt 不是 key 派生函数
  • BCrypt是密码存储功能

  • 您有一个椭圆曲线私钥,要使用用户密码对其进行加密。当然你不想直接使用密码——你想使用密码到派生 一个加密 key 。为此,您可以使用:
  • PBKDF2
  • scrypt

  • 这些都是 key 派生函数(例如基于密码的 key 派生函数)。它们的目的是在给定密码的情况下生成加密 key 。它们被设计成“硬”的。

    您提供这两种算法:
  • 密码
  • 成本参数
  • 所需的字节数(例如 32 ==> 32 字节 ==> 256 位)

  • 它会返回一个 256 位的 key ,您可以将其用作 AES-256 的加密 key 。

    然后您要备份用户的 key

    我猜你然后想要:
  • 将加密的椭圆曲线私钥存储在您的服务器上
  • 在您的服务器上存储他们密码的哈希值

  • 你的问题是:既然你已经通过“散列函数”运行了他们的密码,你不能只使用那个散列作为他们存储的密码吗?

    不!该散列也是保护其私钥的加密 key 。您不希望该私钥在任何地方传输。你不希望它存在于任何地方。完成后应立即从内存中删除该 32 字节加密 key 。

    如果您还希望存储用户密码的哈希值,您应该做的是使用通常用于密码存储的算法:
  • pbkdf2(滥用到密码存储的 key 派生函数)
  • bcrypt(比 pbkdf2 好)
  • scrypt(一种用于密码存储的 key 派生函数;比 bcrypt 更好)
  • argon2(比 scrypt 更好)

  • 您应该通过这些密码存储算法之一单独运行用户的密码。如果您有权访问 bcrypt;在 pbkdf2 上使用它。如果您有 scrypt,请将其用于两者:
  • 加密 key 的推导
  • 密码散列

  • 您系统的安全性来自(除了密码的保密性)用户密码与保护其私钥的加密 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 (以及它的任何转换版本)。

    总结
  • 生成 EC key 对
  • 加密 key = scryptDeriveBytes(密码,盐,成本,32)
  • 加密私钥 = AES256(私钥,加密 key )
  • passwordHash = scryptHashPassword(password, salt, cost)

  • 并上传
  • 加密私钥
  • 密码哈希
  • 关于encryption - bcrypt vs pbkdf2 用于加密私钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40566966/

    相关文章:

    c# - 存储和使用 API key 和 secret 的最安全方式是什么?

    java - 解密 JWE 时出错

    c# - .Net 中(对称)加密的最佳实践?

    node.js - 如何在 Node.js 中重现 Bash HMAC 加密

    php - 使 mt_rand() 尽可能安全

    grails - 配置Spring Boot Security在Grails 3.0中使用BCrypt密码编码

    go - bcrypt 生成不正确的哈希 - 我的用户输入处理是否正确?

    python - 在 OS X : can't find ffi. h 上使用 pip 安装 bcrypt 时出错(已安装 libffi)

    java - 用java加密数据库用户名和密码?

    c - OpenSSL SHA1 未验证 NIST SHAKE 测试 vector ?