前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ActFramework中存储与验证用户密码的机制与应用

ActFramework中存储与验证用户密码的机制与应用

作者头像
老码农
发布2018-06-27 10:39:12
8610
发布2018-06-27 10:39:12
举报
文章被收录于专栏:老码农专栏老码农专栏

@oschina的这篇博客详细讲述了保护密码的机制. 作为应用程序开发者理解这些原理是非常重要的, 但是没有理由在每个项目中依据文中所述去实现自己的保护机制, 框架应该在这方面做出足够的支持.

ActFramework提供简单有效的API来帮助用户处理安全性问题, 其中包括了密码保护与验证. 下面的代码演示如何在应用中使用框架提供的机制:

代码演示

代码语言:javascript
复制
public class User {
    private String email;
    // 保存password hash而不是明文
    private String passhash;
    
    /**
     * 使用`act.Act.crypto().passwordHash(String)`来生成password hash
     * @param password the password text
     */
    public void setPassword(String password) {
        this.passhash = Act.crypto().passwordHash(password);
    }

    ...

    public static class Dao extends EbeanDao<User> {
        ...
        /**
         * 验证用户的方法: 使用email搜索用户, 然后对password做匹配
         * @param email an email
         * @param password a password
         * @return a user if the email and password match, else null
         */
        public final User authenticate(String email, String password) {
            User user = findOneBy("email", email);
            if (null == user) {
                return null;
            }

            return  Act.crypto().verifyPassword(password, this.passhash) ? user : null;
        }
    }
}

算法

ActFramework采用公认最好bcrypt算法处理密码保存与验证

问题

1. 盐在哪里?

Bcrypt采用随机生成盐并且将盐和hash存放在一起

2. authenticate方法为什么不生成hash然后再从数据库中寻找用户

上面的public final User authenticate(String email, String password)这样写不是更简单吗:

代码语言:javascript
复制
public final User authenticate(String email, String password) {
    String hash = Act.crypto().passwordHash(password);
    return findOneBy("email, passhash", email.toLowerCase(), hash);
}

答案是不行. 因为Bcrypt每次都随机生成salt和hash值,所以即便用户使用相同的密码,两次调用Act.crypto().passwordHash(password)生成的值都是不一样的. 必须用emailUser从数据库里面取出之后再使用Act.crypto().verifyPassword(String, String) API来比较

3. 有没有时间攻击防范

JFinal最新版提供了slowEquals方法用于防范这篇博客中讲述的时间攻击问题. ActFramework有这方面的防范措施吗?

答案是必须的, 在Act.crypto().verifyPassword(String)API里面调用Bcrypt的匹配函数, 用的就是JFinal实现的slowEquals逻辑. 值得一提的是和JFinal的实现相比, Bcrypt做了一点优化, 如果字符串长度不匹配的话, 直接短路返回false, 而不会继续slow equals处理.

链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 代码演示
  • 算法
  • 问题
    • 1. 盐在哪里?
      • 2. authenticate方法为什么不生成hash然后再从数据库中寻找用户
        • 3. 有没有时间攻击防范
        • 链接
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档