论坛首页 Java企业应用论坛

一种简单的给MD5加盐算法

浏览 31932 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (3)
作者 正文
   发表时间:2012-10-21  
好不容易想说,这代码至少能看懂了。
但是大神们的回复貌似更犀利啊。
0 请登录后投票
   发表时间:2012-10-21  
huangshiwei19861013 写道
我觉的有一种方法还是比较好的;
假设:user(账户)、passwd(密码)、security(盐码6-8)
security(盐码):默认是123456;
userpassword:passwd和security加密后的字符串;

数据库保存的是user、userpassword;

user、security和passwd由用户存放;

用户验证时:
输入user、passwd、security;

系统验证账户密码时:根据passwd和security生成的加密字符串,和数据库保存的密码比对即可;

客户的原始密码就不能根据数据库中存的破解了;

在加密的过程中,security没有用到额。这样也能进行验证吗?
0 请登录后投票
   发表时间:2012-10-22  
huangshiwei19861013 写道
我觉的有一种方法还是比较好的;
假设:user(账户)、passwd(密码)、security(盐码6-8)
security(盐码):默认是123456;
userpassword:passwd和security加密后的字符串;

数据库保存的是user、userpassword;

user、security和passwd由用户存放;

用户验证时:
输入user、passwd、security;

系统验证账户密码时:根据passwd和security生成的加密字符串,和数据库保存的密码比对即可;

客户的原始密码就不能根据数据库中存的破解了;


只是将一个原始密码分为两部分:passwd, security。 只是这个拆分是由用户自己进行。
0 请登录后投票
   发表时间:2012-10-22  
反查?你的意思是查表?你不能MD5两次甚至更多么?
加盐是是必须的。简单的就是用户ID+PWD+SALT,这样就不影响该用户名。
0 请登录后投票
   发表时间:2012-10-22  
lonelybug 写道
作为一个加密函数,你这程序写的性能未免有点低。

首先你Salt补零的过程用循环就会是一个问题。你为什么不初始化一个用16个‘0’的字符串初始化一个StringBuffer,然后再作后面的工作就可以了。

对于后面48位密码产生也是同样的道理。

还有基本上你这种加密没什么意义,因为48位密码的混合顺序是固定的(人为的),而不是consistent的随机产生。


原来是有工具方法StringUtil.leftPad来补齐的,随手改成了不依赖于别的工具函数的写法了。

你要用StringBuffer,为什么不用StringBuilder呢?其实,你将这个函数改成StringBuffer实现还是StringBuilder实现,还是用+号,性能差异都可以忽略不计。

这也不是加密,只是在摘要中加入干扰项,增加反查的难度的。我前面已经说过了,只要干扰算法是公开的,人家都可以用一样的方式重新构造MD5库再反查。
0 请登录后投票
   发表时间:2012-10-22  
lazy_ 写道
反查?你的意思是查表?你不能MD5两次甚至更多么?
加盐是是必须的。简单的就是用户ID+PWD+SALT,这样就不影响该用户名。


无语,你不能仔细看看帖子吗?
0 请登录后投票
   发表时间:2012-10-22  
ansjsun 写道
为什么不选择多次加密呢?

0 请登录后投票
   发表时间:2012-10-22  
没必要那么复杂吧,MD5之后的字符串是32个16进制字符,假设那么我取其中的2-21共20位,那么你怎么反查也查不出来吧。因为还有12位16进制字符,变数非常之大。
0 请登录后投票
   发表时间:2012-10-22  
1、这是一个很简单的算法,和绝大部分加盐算法一样,只是为了增加通过MD5数据库反查(例如使用http://www.md5.cc/这样的类似的反查数据库)的难度,并不能保证绝对不可反查。

2、作者假定,能够拿到一个应用中用户密码的MD5摘要的人,也能获得该应用的密码摘要形成的算法,以及该算法依赖的外部因素(持久层中的用户ID、用户名、加盐规则、随机数据等)。因此不管是什么样的算法(例如多次MD5以及各种加盐规则),破解者都可以通过将手头的MD5反查库根据你的算法和数据重新运算一遍,以获得针对你的用户数据库的专用的MD5反查库,然后再逐一反查密码明文。

3、考虑到用户密码验证实际上是再次形成MD5摘要的过程,而用户密码验证是一个经常发生的行为,会有高并发的情况。所以一般用户密码验证不允许采用非常复杂和消耗性能的算法,一次验证消耗的CPU时间应在100毫秒之内。我们采用MD5或SHA1的原因一是久经考验的摘要不可逆性;二是性能在允许的范围之内(对于密码这样的短字符串,一台普通PC每秒都可以运算上万次)。

4、因为第3点提到的性能要求,所以根据你的算法重新构建一个专用MD5反查库的时间不会特别长(采用较好的机器和并行计算,可以在有意义的时间范围之内重新形成有100亿条以上记录的MD5反查库)。

5、根据以上2/3/4点,不管采用什么加盐算法,只要算法可以获得,则破解者都可以破解任意一个用户的密码的明文(准确地说是验证该密码是否在MD5反查库中存在,如果存在则能获得明文。特别复杂的密码在MD5反查库中不会有记录,因此即使不加盐也无法破解)。

6、但多次MD5、打乱MD5结果的数位顺序这些算法的安全性要更差一些,便如多次MD5,不管你是几次MD5,破解者只需要根据你算法运算形成MD5反查库,则一次性就破解了你的所有密码。

7、本文中的算法以及MD5(UserName+Password+Salt)、MD5(UserID+Password+Salt)等,是在密码之外有引入了干扰项(称之为盐),因此破解者必须为每一个密码单独形成一个MD5反查库,代价就会非常高,要想破解所有密码实际上已经不可行了。

8、但MD5(UserName+Password+Salt)要求UserName永远不变,MD5(UserID+Password+Salt)要求用户在用户名之外必须有一个不变的UserID。这些额外的要求,导致其适用性没有本文中的算法好。

9、如果以上情况有一条你不需要考虑,则本算法对你确实没有什么用处。
0 请登录后投票
   发表时间:2012-10-22   最后修改:2012-10-22
如果“能拿到用户密码的MD5摘要”的人能拿到密码摘要形成的算法。
那么根据算法能很快就从最终的48位中得到16位随机数和32位MD5字符串(具体是1,4,7...为随机数,0,2,3,5,6,8,...为真正的32位MD5)。然后通过32位MD5反查得到“16位随机数+真正的密码”能很快就知道密码(取16位后的部分就可以了)。

如果“能拿到用户密码的MD5摘要”的人拿不到密码摘要形成的算法。那么随便一种办法就可以了,只要对原始密码进行任意处理就可以了(甚至根本用不着MD5,简单的字符替换就可以了)。别人一样得不到密码。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics