为什么要在密码里加点“盐”

盐(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 的。

转自:http://blog.csdn.net/yang1982_0907/article/details/43483205

(转) 密码学中的“盐值 Salt”的更多相关文章

  1. (转)浅谈MD5加密算法中的加盐值(SALT)

    我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码. 加Salt可以一定程度上解决这一问题.所谓加Salt方法,就 ...

  2. Web应用你加盐了吗?——浅谈MD5加密算法中的加盐值(SALT)

    转自:http://blog.csdn.net/blade2001/article/details/6341078 我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散 ...

  3. (转,学习记录)MD5加密算法中的加盐值(SALT)

    我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码. 加Salt可以一定程度上解决这一问题.所谓加Salt方法,就 ...

  4. SpringBoot整合shiro-MD5盐值加密

    为什么要进行密码加密? 在我们的日常生活中,许多人有着在不同网站上使用相同密码的坏习惯(包括我也是qaq),假如应用程序或服务器出现漏洞,数据被窃取,用户的明文密码直接被暴露给黑客.显然后果将不堪设想 ...

  5. MD5加密算法中的加盐值 ,和彩虹表攻击 防止彩虹表撞库

    一.什么是彩虹表? 彩虹表(Rainbow Tables)就是一个庞大的.针对各种可能的字母组合预先计算好的哈希值的集合,不一定是针对MD5算法的,各种算法的都有,有了它可以快速的破解各类密码.越是复 ...

  6. Spring Security中的MD5盐值加密

    在 spring Security 文档中有这么一句话: "盐值的原理非常简单,就是先把密码和盐值指定的内容合并在一起,再使用md5对合并后的内容进行演算,这样一来,就算密码是一个很常见的字 ...

  7. MD5加密解密以及设置salt(盐值)

    MD5算法 package com.oracle.jsp.util; import java.security.MessageDigest; import java.security.NoSuchAl ...

  8. 给MD5加上salt随机盐值加密算法实现密码安全的php实现

    给MD5加上salt随机盐值加密算法实现密码安全的php实现 如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码.加上sal ...

  9. [区块链] 密码学中Hash算法(基础)

    在介绍Hash算法之前,先给大家来个数据结构中对hash表(散列表)的简单解释,然后我再逐步深入,讲解一下hash算法. 一.Hash原理——基础篇 1.1 概念 哈希表就是一种以 键-值(key-i ...

随机推荐

  1. 【Android开发】如何设计开发一款Android App

    本文从开发工具选择,UI界面.图片模块.网络模块.数据库产品选择.性能.安全性等几个方面讲述了如果开发一个Android应用.现在整理出来分享给广大的Android程序员. 开发工具的选择 开发工具我 ...

  2. 文件打包为zip格式文件下载

    整个思路是这样的: 1.查询数据库中的文件流放到datatable中2.循环datatable将文件流一个个生成文件,放到对应的文件夹中,3.下载某个文件夹下的所有文件a.循环这个文件夹下的所有文件, ...

  3. Android性能优化的一些方案

    优化Dalvik虚拟机的堆内存分配 1)首先内存方面,可以参考 Android堆内存也可自己定义大小和优化Dalvik虚拟机的堆内存分配 对于Android平台来说,其托管层使用的Dalvik Jav ...

  4. 基于Cocos2d-x学习OpenGL ES 2.0系列——OpenGL ES渲染之Shader准备(7)

    Cocos2d-x底层图形绘制是使用OpenGL ES协议的.OpenGL ES是什么呢? OpenGL ES(OpenGl for Embedded System)是OpenGL三维图形API的子集 ...

  5. 关于MultiByteToWideChar与WideCharToMultiByte代码测试(宽字符与多字节字符的转换)以及字符串的转换代码测试

    #pragma once #include <stdio.h> //getchar() #include <tchar.h> #include <stdlib.h> ...

  6. 【Linux】 ftp 主动被动模式

    LNMP 搭建得服务器,在使用ftp时候,报如下错误: 经查,是ftp 主动模式被动模式问题 工具:  Xftp5   ,把被动模式勾 取消 (其他客户端可以网上查一下 相应的 被动模式转主动模式设置 ...

  7. ubuntu 14 root 账户 启用与ssh登录

    ubuntu 14.04 root用户登录 开启root帐号的方法: 为了启用root 帐号(也就是设置一个口令)使用: sudo passwd root 当你使用完毕后屏蔽root帐号使用: sud ...

  8. Linux学习之批量修改文件名

    1. 通过专业的改名命令rename实现 [root@oldboy oldboy]# ll total -rw-r--r-- root root Nov : stu_102999_1_finished ...

  9. struts2漏洞原理

    一.struts2简介: 目前web框架中非常流行的都是mvc设计模式.经典例子例如:python的Django.Flask:java的ssm等.因为使用MVC设计模式,所以在框架内部处理用户数据流参 ...

  10. 去面试H5游戏问的一些问题

    首先肯定是自我介绍,然后问一些基础题,然后问简历上的相关问题. 1. WebSocket和Socket的区别 2.Http和Https的区别,get和post区别 3.进程和线程 4.H5的渲染流程 ...