【问题标题】:Secure password approach安全密码方法
【发布时间】:2015-07-04 09:36:40
【问题描述】:

为了登录目的,我必须创建一个带有用户表的休息服务器。移动设备将连接到此服务器以供用户登录。 我想创建一个安全的系统,我想到了这个解决方案:

用户表:

  • PasswordHash - CHAR(64) 用于存储 SHA256(密码)
  • PasswordToken - CHAR(25) 用于存储随机可能唯一的令牌

用户注册:

  • 设备会生成用户提供的密码的SHA256;

  • 哈希将通过SSL发送到服务器;

  • 服务器会将此哈希值存储在PasswordHash字段中,并将随机令牌存储在PasswordToken字段中;

用户登录:

  • 设备会生成用户提供的密码的SHA256[passwordDevice];
  • 服务器会生成一个 SHA512 的 (PasswordHash + PasswordToken) [hashServer];
  • 服务器将生成 (passwordDevice + PasswordToken) [hashDevice] 的 SHA512;
  • 服务器会生成一个 BCrypt 字符串 (hashServer + serverSideKey) [bCryptServer];
  • 服务器会生成一个BCrypt String of (hashDevice + serverSideKey) [bCryptDevice];

    if (bCryptServer == bCryptDevice) 
       LOGIN OK;
    else
       LOGIN REFUSED;
    

那么,这种方法合适吗?

安全吗?

我可以避免一些操作吗?

我可以优化一些东西吗?

提前致谢。

【问题讨论】:

  • 在客户端生成哈希没有意义。这样,攻击者就可以像使用密码一样使用哈希值。您应该在服务器上创建哈希。
  • 但是如果我发送明文,攻击者可以简单地准备好密码..
  • 用户表在哪里,在服务器上还是在设备上?为什么要在服务器端计算四种不同的哈希值?为什么不使用 bcrypt 存储密码? serverSideKey 的用途是什么?最后,它看起来过于复杂了。
  • 存储原始密码的哈希是一种过时的做法,容易受到rainbow table 攻击。您应该只存储加盐密码的哈希值。
  • 显然您应该永远通过未加密的连接发送身份验证令牌。如果您打算这样做,则散列无济于事。这是原始的混淆,它在没有安全的地方假装安全。不要上当!

标签: security authentication


【解决方案1】:

不,不要那样做。

永远不要传递哈希。哈希必须在服务器上计算。否则它只是一个密码。

仅使用加密哈希。 SHA256 不是一个。使用 bcrypt、scrypt 或 pbkdf2。

它需要尽可能简单,这样你就不会犯错误,而你却让它变得复杂。

【讨论】:

  • 所以我只需要通过带有明确密码的 https url 完成其余请求并存储密码的 bcrypt + 自定义盐?对于登录,我将使用清除密码进行休息调用,并将比较此密码 + 自定义盐的 bcrypt 和存储在数据库中的密码?
  • 是的,虽然密码不是用HTTPS明文发送的,但它是加密的
  • 对于身份验证,您有什么建议?我必须在数据库上存储一个 api 密钥,在登录时返回它,以便在下一个请求中用作标头?
  • @helloimyourmind 有几种方法,比如OAuth,或者见docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
猜你喜欢
  • 2011-07-10
  • 2011-02-03
  • 2011-01-22
  • 2010-09-16
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多