为什么要在密码里加点“盐”
盐(Salt)
在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。
以上这句话是维基百科上对于 Salt 的定义,但是仅凭这句话还是很难理解什么叫 Salt,以及它究竟起到什么作用。
第一代密码
早期的软件系统或者互联网应用,数据库中设计用户表的时候,大致是这样的结构:
mysql> desc User; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | UserName | varchar(50) | NO | | | | | PassWord | varchar(150) | NO | | | | +----------+--------------+------+-----+---------+-------+
数据存储形式如下:
mysql> select * from User; +----------+----------+ | UserName | PassWord | +----------+----------+ | lichao | 123 | | akasuna | 456 | +----------+----------+
主要的关键字段就是这么两个,一个是登陆时的用户名,对应的一个密码,而且那个时候的用户名是明文存储的,如果你登陆时用户名是 123,那么数据库里存的就是 123。这种设计思路非常简单,但是缺陷也非常明显,数据库一旦泄露,那么所有用户名和密码都会泄露,后果非常严重。参见 《CSDN 详解 600 万用户密码泄露始末》。
第二代密码
为了规避第一代密码设计的缺陷,聪明的人在数据库中不在存储明文密码,转而存储加密后的密码,典型的加密算法是 MD5 和 SHA1,其数据表大致是这样设计的:
mysql> desc User; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | UserName | varchar(50) | NO | | | | | PwdHash | char(32) | NO | | | | +----------+--------------+------+-----+---------+-------+
数据存储形式如下:
mysql> select * from User; +----------+----------------------------------+ | UserName | PwdHash | +----------+----------------------------------+ | lichao | 202cb962ac59075b964b07152d234b70 | | akasuna | 250cf8b51c773f3f8dc8b4be867a9a02 | +----------+----------------------------------+
假如你设置的密码是 123,那么数据库中存储的就是 202cb962ac59075b964b07152d234b70 或 40bd001563085fc35165329ea1ff5c5ecbdbbeef。当用户登陆的时候,会把用户输入的密码执行 MD5(或者 SHA1)后再和数据库就行对比,判断用户身份是否合法,这种加密算法称为散列。
严格地说,这种算法不能算是加密,因为理论上来说,它不能被解密。所以即使数据库丢失了,但是由于数据库里的密码都是密文,根本无法判断用户的原始密码,所以后果也不算太严重。
第三代密码
本来第二代密码设计方法已经很不错了,只要你密码设置得稍微复杂一点,就几乎没有被破解的可能性。但是如果你的密码设置得不够复杂,被破解出来的可能性还是比较大的。
好事者收集常用的密码,然后对他们执行 MD5 或者 SHA1,然后做成一个数据量非常庞大的数据字典,然后对泄露的数据库中的密码就行对比,如果你的原始密码很不幸的被包含在这个数据字典中,那么花不了多长时间就能把你的原始密码匹配出来。这个数据字典很容易收集,CSDN 泄露的那 600w 个密码,就是很好的原始素材。
于是,第三代密码设计方法诞生,用户表中多了一个字段:
mysql> desc User; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | UserName | varchar(50) | NO | | | | | Salt | char(50) | NO | | | | | PwdHash | char(32) | NO | | | | +----------+-------------+------+-----+---------+-------+
数据存储形式如下:
mysql> select * from User; +----------+----------------------------+----------------------------------+ | UserName | Salt | PwdHash | +----------+----------------------------+----------------------------------+ | lichao | 1ck12b13k1jmjxrg1h0129h2lj | 6c22ef52be70e11b6f3bcf0f672c96ce | | akasuna | 1h029kh2lj11jmjxrg13k1c12b | 7128f587d88d6686974d6ef57c193628 | +----------+----------------------------+----------------------------------+
Salt 可以是任意字母、数字、或是字母或数字的组合,但必须是随机产生的,每个用户的 Salt 都不一样,用户注册的时候,数据库中存入的不是明文密码,也不是简单的对明文密码进行散列,而是 MD5( 明文密码 + Salt),也就是说:
MD5('123' + '1ck12b13k1jmjxrg1h0129h2lj') = '6c22ef52be70e11b6f3bcf0f672c96ce' MD5('456' + '1h029kh2lj11jmjxrg13k1c12b') = '7128f587d88d6686974d6ef57c193628'
当用户登陆的时候,同样用这种算法就行验证。
由于加了 Salt,即便数据库泄露了,但是由于密码都是加了 Salt 之后的散列,坏人们的数据字典已经无法直接匹配,明文密码被破解出来的概率也大大降低。
是不是加了 Salt 之后就绝对安全了呢?淡然没有!坏人们还是可以他们数据字典中的密码,加上我们泄露数据库中的 Salt,然后散列,然后再匹配。但是由于我们的 Salt 是随机产生的,假如我们的用户数据表中有 30w 条数据,数据字典中有 600w 条数据,坏人们如果想要完全覆盖的坏,他们加上 Salt 后再散列的数据字典数据量就应该是 300000* 6000000 = 1800000000000,一万八千亿啊,干坏事的成本太高了吧。但是如果只是想破解某个用户的密码的话,只需为这 600w 条数据加上 Salt,然后散列匹配。可见 Salt 虽然大大提高了安全系数,但也并非绝对安全。
实际项目中,Salt 不一定要加在最前面或最后面,也可以插在中间嘛,也可以分开插入,也可以倒序,程序设计时可以灵活调整,都可以使破解的难度指数级增长。
PS,文中所谓第一、二、三代密码的称呼,是我自己 YY 的。
为什么要在密码里加点“盐”相关推荐
- 洗脸水里加点盐痘痘去无踪
痤疮患者多为油性皮肤,夏季洗脸时应注意以下几点:坚持用温水洗脸,水温大概在30~40度,这样易于去除油脂,也可用西瓜皮或黄瓜汁敷面15~20分钟.如有脓疱及红肿型的"痘",则可用淡 ...
- 密码和Java中的加解密之MD5加点盐
很多人都用MD5+Base64方式存储密码,这种存储方式 方便.速度快而且由于MD5杂凑算法的几乎不可还原性,攻击者只能通过"猜"去破解密码. 但是MD5对相同的数据返回的信息永远 ...
- 密码加密 加盐 Java PBKDF2 密码哈希代码
如果你是Web开发者,你很可能需要开发一个用户账户系统.这个系统最重要的方面,就是怎样保护用户的密码.存放帐号的数据库经常成为入侵的目标,所以你必须做点什么来保护密码,以防网站被攻破时发生危险.最好的 ...
- 米饭里加点它,4大病症全没了!一定要告诉家里做饭的TA
米饭里加点它,4大病症全没了!一定要告诉家里做饭的TA 2016-03-11 米饭是我们日常饮食中必不可少的东西,但是您一定不知道,米饭除了可以填饱肚子,如果在米饭中加点儿料,那么很多困扰我们的毛病也 ...
- 计算机学院班群头像,【北工大表白墙】计算机类18级3班孙宇辰同学,你是广袤沙漠里的盐。...
原标题:[北工大表白墙]计算机类18级3班孙宇辰同学,你是广袤沙漠里的盐. ----------------------------------- ❤表白1:孙宇辰同学,现在我在四十多公里外昌平,刚刚 ...
- java shiro盐值加密_java中spring-shiro实现密码的MD5盐值加密
看了网上很多教程,都提到有配置spring shiro的密码加密方式,甚至给出了自定义的Class来实现.却很少有通过配置来解决的. 密码的盐值加密方式应该是非常通用的,也可以算是基础吧.按理说spr ...
- 密码MD5加盐加密----注册、校验、修改模块
思路: 单纯的MD5加密容易被碰撞破解,考虑将密码加上一个随机字符串(盐),再一同进行MD5加密,提高安全性. 此时,盐相当于另一半秘钥,需将盐一同存入数据库,用以验证. 实现过程: ...
- 一个简单的方式搞定密码的加盐哈希与验证
过去一段时间来, 众多的网站遭遇用户密码数据库泄露事件.层出不穷的类似事件对用户会造成巨大的影响,因为人们往往习惯在不同网站使用相同的密码,一家 "暴库",全部遭殃. 单向加密 一 ...
- 关于Shiro使用密码加密加盐之后序列化失败的问题(十四)
原文:https://blog.csdn.net/qq_34021712/article/details/84567437 shiro使用密码加盐之后,序列化失败 ERROR Failed to se ...
最新文章
- python身份运算符的语法规则_7 Python语法入门之与用户交互、运算符
- 每日一皮:一个名字打败对手的经典案例...
- [YTU]_2498 (C++类实现最大数的输出)
- getAttribute与getParameter的区别
- Shell命令之ps获取指定进程的进程号
- 【C语言】(指针) 将两个数排序
- HTML+CSS+JS实现计算机功能
- 追赶法求解三对角线性方程组的MATLAB程序
- fastadmin在html中查询数据,常见问题 · fastadmin 常见问题 · 看云
- win7怎么安装消息队列 MSMQ
- Chrome浏览器插件之---FeHelper
- cad计算机快捷键设置,2014年CAD计算机快捷键
- 如何阻止搜索引擎收录指定网页
- 【编程题】构造两两相邻数之和为奇数的矩阵
- 散列:排解冲突(1)
- web课程设计网页规划与设计:文化网站设计——中国水墨风书画艺术网站(12个页面)
- Scrapy入门教程(2)——保存数据
- 重磅:DDN携手潭州学院,全面开启区块链3.0——人才输出、应用落地时代!
- vs qt 无法打开包括文件: “QtCore/qconfig.h”
- 华硕的笔记本为什么按Fn+F9禁用触摸板不起作用了?
热门文章
- Kadane's algorithm学习
- ejb模式_EJB的完整形式是什么?
- Java字符类isUpperCase()方法与示例
- 远控免杀专题(22)-SpookFlare免杀
- html下拉框选中第二个,html通过点击第一个select改变第二关select的内容
- redis 哨兵_Redis哨兵机制的原理介绍
- vs 2019编写汇编并运行调试
- 如何在centos中找到安装mysql_centos上如何安装mysql
- lisp捕捉垂足_定位-'Cal计算器
- 34. 在排序数组中查找元素的第一个和最后一个位置 golang