PHP 项目的用户密码设计

PHP 项目的用户密码设计
Photo by Towfiqu barbhuiya / Unsplash

简单聊一聊用户系统的密码存储设计。

历史变迁

首先,最开始大家用的都是明文存储用户的密码,想着,反正存储在服务端,也只有服务端看得到,

但这些年这么多脱裤事件,终于意识到不能再使用明文了,

于是,大家改用 md5 等哈希算法,为用户密码“加密”,但数据库泄漏后,仍然可以使用 字典攻击 破解。字典攻击 是用一个字典文件,储存了单词、短语、常用密码和他们 hash 后结果。将密码与 hash 结果对比,就能破解。

为了解决这个问题,研发工程师又在密码的hash的过程中加 salt, salt是一串随机值,与 hash 后的密码一起保存在数据库。  这恐怕只能使用暴力破解了,但现在GPU的发展,使得暴力破解成为可能,如果被脱裤,则更容易破解。

同时期的 GPU 的计算单元比CPU多, L1/L2/L3缓存和控制器较少, 所以GPU非常适合做并行且无需内存参与的计算任务。

解决方案

PHP 5.5 开始, 针对于 password, 给出了轻便的解决方案:password_hash(加密)、 password_verify(验证校验)、 password_need_rehash(判断是否需要重新加密);

这一套password解决方案,首先是把 salt 值体现到了 hash 值里面,这样就不需要在维护一个 salt 字段,再者支持了 BCRYPT, ARGON 算法。

BCRYPT 这个算法,相比md5 是一个慢速hash,比较消耗cpu, md5 毫秒级别, bcrypt  0.1 秒级别 ;我们一直想让代码运行的快点再快点,而加密算法反其道而行。

针对这个算法, 并且可以设置 cost,来调整耗时,假设后续机器性能大提升,也可以修改 cost;

上文也提到了,GPU等硬件升级会导致破解速度的加快。

第二种算法,在2015年密码hash竞赛中诞生,并且拿了冠军, 那就是 argon2, 这种算法使用大量内存和大量计算资源进行 Hash 计算, 内存和GPU的数据传输是很慢的(不展开讲),  可能就是 0.2 s 的级别。可以设置 memory_costtime_cost **两种 cost 来调整运算的耗时。

扩展

argon 有3个分支,详细可以线下去了解: PHP 版本 7.2+

  • Argon2d:更快,使用 data-dependent 的内存访问方式,data 是需要 Hash 的 password 和 salt。适合加密货币和不会收到 side-channel timing 攻击的应用。
  • Argon2i:使用 data-independent 的内存访问方式,更适合密码哈希等。他比 Argon2d 慢,因为它需要更多次内存计算(passes)来保护免受 tradeoff 的攻击。
  • Argon2id:是 Argon2i 和 Argon2d 的混合版本,第一次计算用 Argon2i,后续的计算用 Argon2d。如果没有特定的理由,推荐使用 Argon2id。

Argon 需要 安装 sodium 扩展

Read more

CLI 工具多版本管理器 - asdf

CLI 工具多版本管理器 - asdf

asdf 是一个 CLI 工具,可以根据每个项目管理多个工具或语言运行时版本。它就像 gvm、nvm、rbenv 和 pyenv(以及更多)的合一工具!只需安装您语言的插件即可! 这个随手起的名字,可能是目前地表最强版本管理器。 https://github.com/asdf-vm/asdf 一、安装 asdf 以 macbook 为示例 brew install asdf asdf -v asdf version 0.16.2 0.16.0 以上命令有较大变更,详见:https://asdf-vm.com/guide/upgrading-to-v0-16.html#breaking-changes 本文使用

By brian
golang proto api 校验国际化 protovalidate

golang proto api 校验国际化 protovalidate

众所周知,protobuf 原型文件扩展很多功能,比如生成 http 接口层代码,顺势就有了生成接口参数校验代码的需求。 早期可以使用https://github.com/bufbuild/protoc-gen-validate 来实现,通过生成特定的 go 代码的方式来实现校验。 github 中也提到目前趋于稳定,不会有更多新特性的支持,推荐大家使用新的版本 protovalidate,https://github.com/bufbuild/protovalidate 。该版本是protoc-gen-validate 的“精神继承者”。它不需要任何代码生成并支持自定义约束。 现在我们尝试新版本,并且增加国际化支持。 go get github.com/bufbuild/protovalidate-go import "github.com/bufbuild/protovalidate-go" syntax = "proto3"; package

By brian
沪ICP备2022013452号-1