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

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

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

代码演示

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)这样写不是更简单吗:

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处理.

链接

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏新智元

Python 3.7.0 来了!

【新智元导读】Python官网静悄悄地发布了一条大消息:正式发布 Python 3.7.0!同时发布的还有Python 3.6.6稳定版。官网刚刚更新了可下载文...

1210
来自专栏IMWeb前端团队

nodejs中错误捕获的一些最佳实践

本文作者:IMWeb yisbug 原文出处:IMWeb社区 未经同意,禁止转载 本文内容大部分来自 https://www.joyent.com/...

1946
来自专栏逆向技术

16位汇编第第四讲常用的7种寻址方式

常用的7中寻址方式 昨天稍微讲了一下,立即数寻址,今天继续讲解寻址方式. (注意,这个属于简陋版的,写了4个小时的博客,也就是第一版,保存了一下,但是博客出问题...

1845
来自专栏york技术分享

sed 使用教程 - 通读篇(30分钟入门系列)

和上篇 awk 分享一样,作为通读性的分享,不想引入太过复杂的东西,依然从日常工作中碰到的 80% 的需求出发,重点阐述最重点的部门,工作原理等,普及一些对se...

41922
来自专栏用户画像

4.2.2 常见的数据寻址方式

如单地址的指令格式,就不是明显地在地址字段中指出第二操作数的地址,而是规定累加器ACC作为第二操作数,指令格式明显指出的仅是第一操作数的地址。因此,累加器ACC...

652
来自专栏Petrichor的专栏

git: .gitignore文件 (忽略文件)

Note: 切记目录名后面 一定要加 反斜杠 / ,不然会当成 单文件 处理。

732
来自专栏专注 Java 基础分享

Java并发之线程间的协作

     上篇文章我们介绍了synchronized关键字,使用它可以有效的解决我们多线程所带来的一些常见问题。例如:竞态条件,内存可见性等。并且,我们也说明了...

2049
来自专栏python3

Django的路由控制

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于...

1662
来自专栏orientlu

FreeRTOS 消息队列

上面这几中方式中, 除了消息通知, 其他几种实现都是基于消息队列。消息队列作为主要的通信方式, 支持在任务间, 任务和中断间传递消息内容。 这一章介绍 Fre...

1612
来自专栏无题

《深入理解JVM》阅读笔记以及问题整理

对阅读周志明先生的《深入理解JVM》产生的疑问与感悟以及要点进行总结。 想这种技术书应该反复读,最近又阅览了一次,才对GC部分有了一个大概的框架,可是细节部分依...

3356

扫码关注云+社区