哈希(Hash)算法就是单向散列算法,它把某个较大的集合P映射到另一个较小的集合Q中,假如这个算法叫H,那么就有Q = H(P)。对于P中任何一个值p都有唯一确定的q与之对应,但是一个q可以对应多个p。
作为一个有用的Hash算法,H还应该满足:H(p)速度比较快; 给出一个q,很难算出一个p满足q = H(p);给出一个p1,很难算出一个不等于p1的p2使得 H(p1)=H(p2)。
正因为有这样的特性,Hash算法经常被用来保存密码,我们使用相应的哈希算法对于密码整体P(注意是整体P),计算出它的q,并进行存放。而在密码比对时,使用输入的密码经过哈希函数算出的q和我们已经在存放的该用户的对应的密码经哈希算出的q来进行对比。
这样即使别人知道了q,很难由q推算出p。或者很难推算出一个p使得这个p经过哈希函数算出的q能够和原来的q匹配从而破解密码,————这样不会泄露密码明文,又可以校验输入的密码是否正确。常用的 Hash算法有MD5、SHA1等。
但是需要注意有破解的方法,一种是暴力破解法,就是对于所有的密码情况,我们算出它的q,直到它等于q,这种方式需要计算相当长的时间。第二种就是使用内存换时间,我们先把所有的情况的q都计算出来,存放在一个Tables中,然后一个个去查询,这种方式需要相当大的存储空间。
现在还有第三张折中方法,彩虹表
彩虹表的根本原理就是组合了暴力法和查表法,并在这两者之中取得一个折中,用我们可以承受的时间和存储空间进行破解。它的做法是,对于一个Q = H(P),建立另一个算法R使得 P = R(Q),然后对于一个p,这样进行计算:
p0 -H-> q1 -R->p1 -H-> q2 -R->p2 -H-> q3 -R->p3 … -H-> q(n-1) -R->p(n-1) -H-> qn -R->pn(这里的n使我们自己选取的,如果n很大,那么就代表我们可以用一个p0 pn对记录更多的数据)
简单的说,就是把q用H、R依次迭代运算,最后得到pn,n可能比较大。最后我们把p0和pn都存储下来,把其他的结果都丢弃。然后用不同的p0代入计算,得到多个这样的p的对子。
我们在做破解的时候,给出了一个q,我们来寻找p。我们先把q做一次R运算得到一个值例如叫c1,然后把c1和每一个p对的最后一个做比较,假如和某一个 pn相等,那么有可能这个pn往前推得到的p(n-1)就是我们在追寻的p,为了验证我们把pn对应的p0再做一次链式计算,比对qn是否就是我们之前给出的q,如果是,很明显p(n-1)就是我们在追寻的p,因为 p(n-1) -H-> qn。如果不是就继续寻找直到遍历所有的q0qn对。
事情还刚刚开始,我们再算q -R-> c1 -H-> -R-> c2,再比对c2是否是p(n-1),如果是,那么p(n-2)就可能是p,因为p(n-2)-H-> q(n-1) -R->p(n-1) -H-> qn -R->pn;再算c3、c4直到c(n-1).//该段话有待检验
所以为了阻止黑客们使用彩虹表破解密码,我们考虑使用MD5+salt的方式,这种方式的思路就是既然你可以得到我的密码散列值并通过散列表或是彩虹表破解我的密码,那么我只要我使用某种方式使你的散列表失效就可以了,这里就是给用户输入的明文密码加上一个随机字符串(这里的随机字符串就是salt,我们可以想象成作料)形成一个新的字符串,然后再散列。在存储经散列后的密码的同时也要将salt存储到对应的用户名中去,在下次用户输入密码验证时,就将密码和数据库中的salt相加再散列再和原来用户注册的密码散列值比对。详见
http://blog.sina.com.cn/s/blog_59a133f7010124ee.html
随着计算机的飞速发展,使用CUDA穷举所有情况,快速破解密码称为可能,那么我们该怎么办?我们需要一个不随计算机性能增长而加速的算法,这里就提出了bcrypt算法:
引用
因为bcrypt采用了一系列各种不同的Blowfish加密算法,并引入了一个work factor,这个工作因子可以让你决定这个算法的代价有多大。因为这些,这个算法不会因为计算机CPU处理速度变快了,而导致算法的时间会缩短了。因为,你可以增加work factor来把其性能降下来。
可以参考
http://coolshell.cn/articles/2078.html
分享到:
相关推荐
MD5 的全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。 作用:把一个任意...
平时用的md5+sha1加密的js文件,用法: <script type="text/javascript" src="js/md5.js"> <script type="text/javascript" src="js/sha1.js"></script> var hash = hex_md5(name+" "+password); var date = new ...
crypt-md5源代码,这是linux里面最常用密码校验算法,利用salt和password和crypt函数生成hash值,原理就是用数次md5函数
5.2 Hash函数MD5 5.2.1 MD5算法 5.2.2 MD5的安全性 5.3 安全Hash算法SHA-1 5.3.1 SHA-1算法步骤 5.3.2 SHA-1和MD5的比较 5.4 基于分组密码与离散对数的Hash函数 5.4.1 利用分组密码算法构造Hash函数 5.4.2 基于...
用C语言实现MD5哈希函数,它是将文件的每一行进行MD5加密,输出一个128位的哈希值。
hash函数对于从事计算机安全和网络安全的工作的朋友们一定不陌生,网上也有很多人写过这个程序,本程序附有自己的详细注释,对那些对md5函数不是很了解的朋友会大有帮助……
//此函数用于生成hash字符串 std::string hash = BCrypt::generateHash(password); //用于判断密码和数据库password加密后的字符串是否匹配 std::cout << BCrypt::validatePassword(password,hash) << std::...
BCrypt 软件包中使用的BCrypt密码哈希函数的Swift实现。用法杂凑 import BCryptlet digest = try BCrypt. Hash . make ( message : " foo " )print (digest. string )核实 import BCryptlet digest = " $2a$04$TI13...
密码学实验(全部题目+完整代码:Hash算法MD5,DES-CBC,基于口令的加密,CBC-MAC,数字信封, 数字签名,DH)
md5和sha-1算法代码及验证文件 在vc6.0调试运行无误,
Hash函数及数字签名应用实验 验证码的实现过程
libbcrypt的围绕bcrypt密码哈希的C ++包装器如何建立这个这是一个基于CMake的项目: git clone https://github.com/trusch/libbcryptcd libbcryptmkdir buildcd buildcmake ..makesudo make installsudo ldconfig...
RS-Hash Function Value: " + ghl.RSHash(key)); System.out.println(" 2. JS-Hash Function Value: " + ghl.JSHash(key)); System.out.println(" 3. PJW-Hash Function Value: " + ghl.PJWHash(key)); System....
关于hash函数的ppt
bcrypt安装将以下内容添加到Cargo.toml:bcrypt =“ 0.8”最低Rust版本为1.34.0(或使用分配功能时为1.36.0)bcrypt安装将以下内容添加到Cargo.toml:bcrypt =“ 0.8” Rust的最低版本为1.34.0(或使用alloc功能而...
这是Niels Provos和David Mazieres在“”中描述的OpenBSD Blowfish密码哈希算法的实现。 它的核心基于 ,但经过大量重构,现代化并具有大量更新和增强功能。 它支持所有常见,具有安全敏感的API,并且已针对一系列...
md5 hash file and string c++ coding
本程序是c++程序,实现MD5的hash摘要
本文主要介绍了几种常见的破解密码的方法,为密码加盐(Salt)以及在.NET中的实现等。具有一定的参考价值,下面跟着小编一起来看下吧
这是清华大学王老师报告PPT,介绍了密码HASH函数上研究的最新成果