点击上方“终端研发部”,选择星标

回复“资源”,领取全网最火的Java核心知识总结~

作者:小蒋不素小蒋

www.cnblogs.com/xjnotxj/p/12716981.html

前言

最早在大学的时候,只知道用 MD5 来存用户的账号的密码,但其实这非常不安全,而所用到的哈希函数,深入挖掘,也发现并不简单……

一、普通的 Hash 函数

哈希(散列)函数是什么就不赘述了。

1、不推荐

RC4, MD4, MD5, SHA-0, SHA-1, DES, 2DES 等

2、推荐

SHA-2(SHA-256, SHA-384, SHA-512)、SHA-3、Blake2 等

美国国家标准和技术协会(NIST)宣布,2010 年后开始逐步取消 SHA-1 作为安全哈希算法的资格,取而代之的是其更强大的变异算法:SHA-224、SHA-256、SHA-384 和 SHA-512。无论是否遵循 NIST 的标准,至少使用 SHA-256 算法加密密码总是好的。

二、应对普通哈希容易被破解的策略

就像攻与矛的互相增强,哈希函数哪怕用到 SHA-3 以上,都还是有被轻易破解的风险。于是我们有其他额外的办法来解决这个问题。

1、加盐(salt)

加盐就是对目标字段哈希前,拼接上另一个字段(salt)。

注:盐值加到字段之前较为普遍。

加盐对防彩虹表很有效。

注意点:

  • 盐不能太短

  • 盐不能重复使用(否则一破解,所有的都遭殃)

  • 盐随机变化(例如,虽用户名不重复,但用户名不能拿来当盐)

  • 盐的本质是将无差别攻击转化为针对性攻击。

1.1、【拓展】针对 salt 的另一种做法 —— HMAC

HMAC(Keyed-Hashing for Message Authentication)其实也是一种特殊的加盐,只是这个 salt 用更安全的密钥代替了。

具体介绍:

https://www.cnblogs.com/xjnotxj/p/11934756.html

2、慢哈希

高端的显卡(GPU)和定制的硬件可以每秒进行数十亿次哈希计算,因此这类攻击依然可以很高效。为了降低攻击者的效率,我们可以使用慢哈希,即迭代进行很多次哈希运算。

那么迭代多少次比较安全呢?来自 NIST 官方的建议:

  • 2000 年 9 月,建议迭代一千次

  • 2015 年 - 2018年,建议迭代一万次

  • 2017 年 6 月,建议迭代十万次

三、密码哈希函数(Password Hash)

密码哈希函数(Password Hash)可以用来应对普通哈希容易被破解的问题(也用到了上面所提到的两个策略)。

下面列举的顺序是按照时间顺序,安全程度和推荐指数也逐级递增。

1、PBKDF2

比较老,很少有人用了,略。

2、Bcrypt

这是我司目前用的。(不过有过时的隐患,建议换掉)

(1)介绍

bcrypt 是由 Niels Provos 和 DavidMazières 基于 Blowfish 密码设计的密码哈希函数,于 1999 年在 USENIX 上提出。

bcrypt 函数是 OpenBSD 和其他系统(包括某些 Linux 发行版,例如 SUSE Linux)的默认密码哈希算法。

(2)使用(Node.js)

安装:

npm i bcryptjs

bcryptjs 跟 C++ 的 bcrypt 兼容,但因为是纯 JavaScript 编写的,因此速度较慢(约 30%)。

用法:

//Sync 方法(Async 方法略):const bcryptjs = require('bcryptjs');// 1、生成 安全因子
const salt = bcrypt.genSaltSync(10);
// 2、执行 哈希函数
const password = bcryptjs.hashSync(plainPassword, bcryptjs.genSaltSync(salt));// 另一种方法:快速执行
const SALT_FACTOR = 10;
const password = bcryptjs.hashSync(plainPassword, bcryptjs.genSaltSync(SALT_FACTOR));// 3、比较是否相等
bcryptjs.compareSync(plainPassword, password);

注:代码里出现的安全因子,值的大小决定了哈希函数会有多慢。(即慢哈希)

3、Scrypt

没用过,略。

4、Argon2

(1)介绍

2013 年 NIST(美国国家标准与技术研究院)邀请了一些密码学家一起,举办了密码哈希竞赛 PHC(Password Hashing Competition)。Argon2 在 2015 年 7 月赢得了冠军。

大赛列出了参赛算法可能面临的攻击手段:

  • 哈希算法破解(原值还原、哈希碰撞等);

  • 查询表/彩虹表攻击;

  • CPU 优化攻击;

  • GPU、FPGA、ASIC 等专用硬件攻击;

  • 旁路攻击;

(2)使用(Node.js)

1、准备

You can skip this p if the prebuilt binaries work for you.You MUST have a node-gyp global install before proceeding with install, along with GCC >= 5 / Clang >= 3.3. On Windows, you must compile under Visual Studio 2015 or newer.node-argon2 works only and is tested against Node >=10.0.0.---OSX
To install GCC >= 5 on OSX, use homebrew:$ brew install gcc
Once you've got GCC installed and ready to run, you then need to install node-gyp, you must do this globally:$ npm install -g node-gyp
Finally, once node-gyp is installed and ready to go, you can install this library, specifying the GCC or Clang binary to use:$ CXX=g++-6 npm install argon2
NOTE: If your GCC or Clang binary is named something different than g++-6, you'll need to specify that in the command.

2、安装

npm i argon2

3、使用

const argon2 = require('argon2');(async () => {try {// const hash = await argon2.hash("password");// 更多选项(以下都是默认值)const hash = await argon2.hash("password", {type: argon2.argon2i,hashLength: 32, // 哈希函数输出的字节长度(请注意,生成的哈希是使用Base64编码的,因此长度将增加约1/3)timeCost : 3, // 时间成本是哈希函数使用的通过次数(迭代次数)memoryCost: 2 ** 16, // 默认 4096(单位 KB,即 4MB)parallelism :1, //用于计算哈希值的线程数量。每个线程都有一个具有memoryCost大小的内存池})console.log("hash", hash)const is = await argon2.verify(hash, "password")console.log("is", is) // true} catch (err) {console.error("err", err)}
})()

(3)参数

1、type:

  • argon2d 更快且对GPU攻击具有高度抵抗力,这对于加密货币很有用

  • argon2i 速度较慢且可以抵御权衡攻击,因此首选用于密码哈希和密钥派生

  • argon2id 是上述内容的混合组合,可以抵抗GPU和权衡攻击

因为我们是用于密码的 hash,用默认的 argon2i 即可。Java知音公众号内回复“面试题聚合”,送你一份面试题宝典!

2、(慢)哈希相关参数

① memoryCost 内存开销,它定义了内存的使用情况

好的起点是 0.75 *(RAM / number_of_users) 起步。

② parallelism 并行程度,它定义了线程的数量

最佳起点是内核数。

③ timeCost 时间开销,它定义了执行的时间

建议在系统上运行它,并确定与内存和处理器使用时间限制相匹配的最大参数。

如前所述,本质是在安全性和可用性之间取得平衡。

3、其他参数

  • salt:默认值是未设置,将生成加密安全的随机盐。

  • saltLength:默认16。

  • version:您不应更改此设置,因为最新版本更强大。

5、密码哈希是如何解决普通哈希容易被破解的问题

上面介绍了 二、应对普通哈希容易被破解的策略 ,我们可以看看密码哈希是如何运用并符合这些策略的。

(1)针对 salt

密码哈希使用 CSPRNG(Cryptographically Secure Pseudo-Random Number Generator)密码学安全伪随机数生成器生成盐。

CSPRNG 是加密安全(Cryptographically Secure)的,(加密安全的意思即)意味着用它产生的随机数更加随机,且不可预测。

普通的计算机随机数算法并不是很随机。

注:盐值本身就在存在于哈希后的字符串中(其实还可能包括版本、慢哈希迭代次数等),当调用跟明文比对的方法时,模块内部会提取出盐值进行验证。

(2)针对 慢哈希

Bcryoy 的安全因子和 Argon2的 timeCost 参数,都是针对慢哈希的配置。

6、结论

我司使用的 Bcrypt 其实在今年(2020年),已经不安全了,推荐至少使用 Scrypt,有条件上 Argon2。

四、常见问题

问1:我用我自己实现哈希算法,不用公开现成的,越古怪越好,坏人不就猜不到了吗?

答:不建议。

首先介绍下密码学上的柯克霍夫原则(Kerckhoffs's principle,也称为柯克霍夫假说、公理、或定律),由奥古斯特·柯克霍夫在 19 世纪提出:即使密码系统的任何细节已为人悉知,只要密匙(key,又称密钥或秘钥)未泄漏,它也应是安全的。信息论的发明者克劳德·香农则改成说:“敌人了解系统”,这样的说法则称为香农箴言。

基于这个原则:

  • 你自己实现的再古怪,毕竟你不是密码专家,很难确保不被坏人破解(可能自己实现后看似复杂,实际更容易破解了)。

  • 如果自己包含哈希算法的代码泄露,它很脆弱,难保不会被坏人破解。

问2:既然现在都是 https,前端传给后端的明文密码,就懒得加哈希了,可以吗?

还是建议前端也进行哈希(虽然前端的哈希算法容易暴露)。不要漏掉任何一个环节。

五、实操

Dropbox 公司曾公开分享过自己对用户账号的密码加密的策略,使用了三层加密:

1、password

即明文密码。

2、SHA512

在 bcrypt 前做 SHA512,是因为有些 bcrypt 实现会把散列值长度截至 72 字节,从而降低了密码的熵值,而有的则允许变长密码,这样容易受到 DoS 攻击。使用 SHA512 散列可以得到固定长度的 512 字节散列值,避免了上述的两个问题。

”而有的则允许变长密码,这样容易受到 DoS 攻击“,这句话我不是很理解,待写。

3、bcrypt

上面说过,不赘述了。

4、AES256

AES256 会用到密钥,俗称胡椒粉(pepper)。密钥需要被单独存储,最好存储在外部系统:如物理上隔离的服务端、甚至特殊的硬件设备(如 YubiHSM) 。

这里的 AES256 也可以用 HMAC 代替。不过前者安全性更好些。

IntelliJ IDEA 快捷键终极大全,速度收藏!

重磅:Java 14 正式发布了!

Java 中一个令人惊讶的 BUG

赶紧卸载Notepad++!事实已证明,它更牛逼……

老板居然让我抗住高并发,我要怎么限流?

又到315,BAT大厂是如何打假的?

YYYY-MM-DD 的黑锅,我们不背!

别再 select * 了,送你 12 个查询技巧!

Google 开源的依赖注入库,比 Spring 更小更快!

相信自己,没有做不到的,只有想不到的

在这里获得的不仅仅是技术!

喜欢就给个“在看

数据库里账号的密码,怎样存放更加安全?相关推荐

  1. 数据库里账号的密码,这样存放最安全!

    作者:小蒋不素小蒋 来源:cnblogs.com/xjnotxj/p/12716981.html 最早在大学的时候,只知道用 MD5 来存用户的账号的密码,但其实这非常不安全,而所用到的哈希函数,深入 ...

  2. 探讨一下,数据库里账号的密码,怎样存放更加安全?

    作者:小蒋不素小蒋 www.cnblogs.com/xjnotxj/p/12716981.html 最早在大学的时候,只知道用 MD5 来存用户的账号的密码,但其实这非常不安全,而所用到的哈希函数,深 ...

  3. 数据库登录账号和密码的验证

    易语言数据库密码验证 1,首先我们需要创建一个用来存储密码的数据库 分别在数据库中建立一个存储账号和密码的名称,类型为文本型, 2,数据库创建好了以后,我们需要手动把原始账号和密码添加到数据库里,打开 ...

  4. 修改zabbix后台登录账号和密码,提升为超级管理员

    最近部署zabbix监控,发现管理员并没有给我创建超级账户,这就很尴尬了,在前台登录的时候,看不见任何监控数据,不想麻烦管理员了,so,我只好进数据库后面插入一条账号了,期间并没有向管理员咨询任何信息 ...

  5. Oracle默认数据库角色账号密码

    Oracle默认数据库角色账号密码 角色 账号 密码 普通用户 SCOTT tiger 普通管理员 SYSTEM manager 超级管理员 SYS change_on_install

  6. 关于数据库账号和密码加密问题

    关于数据库账号和密码加密的问题 采用md5进行加密 md加密是不可逆.但是现在md5可以被破解,怎么办?加盐处理 package com.pug.zixun.common.utils.pwd;impo ...

  7. 图片存放在服务器还是数据库里的解释?

    图片一般存放在服务器还是数据库里? 是把路径和文件名存在数据库还是把图片转成二进制存在数据库?一般是哪种方法? 当然是图片存放在服务器上,数据库存路径. 原因: 如果你把图片数据保存于数据库中,那么你 ...

  8. 360 浏览器设置里安全设置里清除上网痕迹中没有“管理保存过的账号和密码”这个选项

    360浏览器设置里安全设置里清除上网痕迹中没有"管理保存过的账号和密码"这个选项 点击360浏览器右上角"管理"->"管理"里的&qu ...

  9. mysql存放double_double在数据库怎么定义 如何将double数组转成二进制存到数据库里...

    double是什么数据类型?它有什么作用? 怎么在MYSQL数据库的表中插入一个double型数据? 我插入double型数据的时候MYSQL会直接将double型数据四舍五入为整数,如double型 ...

最新文章

  1. Linux进程间通信(IPC)-------消息队列
  2. 产品经理需要去客服部门轮岗吗?
  3. 发现2017年最好的CSS框架
  4. Module System of Swift (简析 Swift 的模块系统)
  5. ectouch手机商城首页调用指定分类下的商品
  6. 灵魂拷问:你写的SQL一般有几个join ?​
  7. Ae效果控件快速参考:3D 通道
  8. 目标跟踪 | 目标跟踪算法总结
  9. VTP(VLAN中继协议/虚拟局域网干道协议 VLAN Trunking Protocol)
  10. android n改铃声,来电铃声自定义,我”响“你快乐!
  11. 金陵科技学院c语言校内题库,金陵科技学院校内二级复习题
  12. 我是如何用问卷调查小程序来赚钱的
  13. 是什么让复旦校长彻夜难眠?
  14. mit数据库 matlab,[zz]MIT-BIH开放数据库使用指南
  15. 洛谷P1018乘积最大题解--zhengjun
  16. 功能测试的用例测试方法
  17. ASP.NET小Tips两则
  18. Kubernetes监控体系(11)-alertmanager安装和配置
  19. 光纤传感器实验模块_光纤位移传感器实验教学改进
  20. 油烟在线监控系统云平台 油烟环保监测云平台 油烟大数据平台

热门文章

  1. Vue.js+ElementUI+vant生成动态表单配置
  2. 如何一天制作100个原创短视频?
  3. 视频教程-桫哥-GOlang-12数据库-Go语言
  4. “蚂蚁呀嘿” 特效安卓 IOS 快速生成APP找到了!
  5. 火影忍者ol服务器维护中,火影忍者ol3月17日更新维护到几点
  6. drawrect导致内存暴涨分析
  7. 企业为什么要开展互动营销 互动营销对企业的作用是什么 - whale 帷幄
  8. 爱的C语言歌曲,爱的C语言(伴奏)
  9. 服务器显示网络不稳定,服务器网络丢包的原因以及解决办法
  10. 用Python定义一朵郁金香