针对密码泄漏事件,都有哪些相对安全的密码加密规则?


对于 CSDN 明文存储密码并测漏一事,我实在无力吐槽。

传统的直接md5(password)弱爆了,密码字典一下子就查出来了。所以,希望大家能给我提供一些值得在今后开发中使用的密码加密规则。

我常用的方法是用户提交时,先用 JavaScript MD5 将密码在本地加密,提交到服务端,服务端取用户表中某个字段(比如注册时间)再加密一次md5(datetime+md5(password)),存储二次加密后的密码,自认为这样相对安全,但还是觉得有些许不妥,希望能指出。

加密 md5
3条评论 | 修改 | 链接
  • ThreeZhiWang

    密码字典只能查出常用的,非常用的很难查出来,碰撞破解的话耗时很长。而且MD5密码的更大的意义是表明,网站不会需要知道你的明文密码罢了。你提到的方法无需加某字段,双次MD5就很难破解了。

  • ninehills

    那以后登录怎么办,datetime一变,岂不是永远密码不匹配。。

  • 轻声

    @ninehills 楼主讲的是某个固定的字段,比如datetime,指的是注册的时间,是不会变的

14 个回答


  • Chris Yue Chris Yue 495

    其实关于安全问题的讨论或者防御方法很多手册都写得非常好,真不知道现在的程序员有没有好好看过这些文字。

    比如说php,已在md5的手册上给出了以下连接:http://cn2.php.net/manual/en/faq.pass...

    我大概翻译一下要点:
    1. md5, sha1, sha256都不适合用来做密码的加密,以上函数都是为了快速有效的验证而设计(我想是指验证文件等运用),所以使用现代的计算机技术,是完全有可能实现暴力破解的

    2. 加密password最好是使用更复杂算法的方法比如crypt,并且使用“加盐值(salt)”,楼主所说的方法就是一种加盐法,也就是将原密码通过一些有规律的变化再加密。

    3. 第三点解释什么是salt,上面已经解释了,使用了salt以后就算暴力破解了也不见得能立马能看出原密码来,必须知道变化的规律才行

    后来我有注意到楼主在客户端用md5加过一次密,我的第一感觉是没什么用,因为客户端的js代码谁都看得见,知道加密的规则,所以这么做如果是防截取的话,感觉用处不是特别大,而且我直接使用截取到的加密后的密码直接传输到服务器端,服务器也看不出什么差别来。

    对于传输层来说,还是老老实实用https靠谱点儿

    Chris Yue 495

    4条评论 | 修改 | 链接
    • laohyx

      crypt也是单向加密的,但是sha1,md5的随机性和抗碰撞性已经很好了。加盐的目的是阻止彩虹表,暴力破偏依然没用……

    • Chris Yue

      @laohyx 加密必然是单向,用双向难道还允许decode是吧?我想问问什么叫随机性和碰撞性?我猜是匹配几率的意思?不过这要看怎么定义“很好”了,什么程度叫做“很好”呢,每个人或者每个网站都有不同的感受,对于我来说,一般帐号没什么价值的网站,也许md5+稍微复杂的salt规则也够了,但是重要的网站,md5甚至是sha1,也许都不够,因为以现今的技术,暴力还原可能做到,还原以后,就算你加盐规则再复杂,你怎么知道获取这些密码的人就一定不能猜测到你的加盐法。所以,在帐号非常有价值的网站,至少对于我来说,使用更加复杂的加密算法能给我更多的信心,因为第一步都很难达成的话,能完全还原密码的几率就无限趋于0了

    • laohyx

      @Chris Yue 事实上规则再复杂都是没用的,因为网站能被拖库,那么代码也基本不保。加盐对安全性的提升,仅限于防止彩虹表。因为盐也在数据库里,所以依然可以暴力破解之……所以如果真的拖了库,再复杂的算法也难保安全,假如真的有人盯上你的话……不过服务器会越来越安全,反而客户端攻击可以绕过这些……

    • 显示隐藏的1条评论
  • joyqi joyqi 4.1k

    首先用明文保存用户密码非常不道德,而且做法很业余,万一被攻破用户要改的地方就多了。

    应该说纯粹的md5哈希也已经非常不安全了,现在黑客们从各个站暴库而流传的地下猜解字典已经非常大了。所以国内对用户密码的处理普遍还处在一个非常初级的阶段,你只能寄希望于黑客别找上你。

    现在国外比较流行的对密码的处理方法主要是在md5的基础上,加上一个随机的扰码(salt),这样你的密码哈希后的值也是随机的了,即便被别人拿到这个值,也无法还原出你真实的密码。在php上有很著名的phpass库(http://www.openwall.com/phpass/),目前wordpress就是使用的这种方法。

    对纯哈希的研究,除了使用位数更大的hash以外(现在sha算法已经可以做到512位),还可以使用blowfish这种使用密码算子的算法。我记得看过一片文章介绍这种算法,因为它使用算子做计算,你可以根据自己服务器的运算速度,选择一个合适的算子组合,这样你可以控制它的运算时间,比如说在我的服务器上我需要0.5秒才能hash出结果,那如果别人拿这个hash值去做碰撞实验,基本上是不可能的结果,即便是用超级计算机也很慢了。不过这种算法的缺点就是太耗cpu了,一般网站没什么必要。

    3条评论 | 修改 | 链接
    • ShingChi

      Typecho 新版本会不会改成这样的算法呢

    • Chris Yue

      第一句话非常之赞同,每个站长都有义务保护好自己用户的密码。明文记录密码或者简单md5,不是因为程序员无知就是因为想看别人的常用密码。希望是无知,诚信出了问题更恐怖。 昨天跟今天我都忙着修改我的第二等级密码,烦死了……

    • 白开水

      看来看去,只有这个答案有点像样子

  • 徐明明V 徐明明V 25

    我的感觉这样已经够了:其实MD5算法本身已经够牛逼了,但是因为大家的密码都是一些常用的密码,所以就有了密码字典。现在你再加一个salt, 破解密码的难度又加大了。他需要做下面的事情:

    1. 猜你的salt是哪个字段
    2. 猜到你的salt是哪个字段之后,需要知道对应的字段的值(你这里的注册时间)
    3. 即使知道这些也没办法用密码字典来查了。
    4. 即使他知道了密码的最后加密值,那么也需要用下面的公式一个个来试了

    MD5(salt + 所有可能的常用密码) =? 加密后的密码值

    我感觉一般来说这种加密方式应该够了。

    0条评论 | 修改 | 链接
  • Magic Jacky Magic Jacky 2

    MD5,sha都不是加密的手段,就算是加salt也好,我们应该使用bcrypt加密密码,请参考http://codahale.com/how-to-safely-sto...
    上面有详细说明原因。

    0条评论 | 修改 | 链接
  • loki loki 17

    其实对单个账号加随机salt已经可以了,至少拿到暴库无法批量得到所有用户密码。注意是针对单个账号的随机salt,单一salt一旦泄露也就无意义了。

    虽然即使这样针对单个用户的破解仍然是可行的,但是对整个库的破解就成本太高了。

    loki 17

    0条评论 | 修改 | 链接
  • Charlie Jade Charlie Jade 28

    没有攻不破的盾, 再好的加密措施, 只是多加了几道门, 再者设计复杂的方法的话, 用户体验又不好.

    让用户输入一个超强的密码 ( 如:必须带数字大小写字母加上特殊符号,并且不允许出现字典里面找得到的单词, 密码位数在 15 位以上 ), 最后只会导致, 用户找个地方把密码记录下来, 如记在小字条上然后放到钱包里面!

    但是, 直接明文储存, 也太不负责任了, 挺愚蠢的做法!

    简单但有效的加密措施为:
    salt = 随机; // 加多些干扰因素
    password = md5( md5(明文密码) + salt );

    数据库存的是 password 和 salt ! 且每一次登录的时候重新更新 salt 和 password ;

    0条评论 | 修改 | 链接
  • JemyGraw JemyGraw 125
    import hashlib
    print hashlib.md5('user_password'+hashlib.md5('salt').hexdigest()).hexdigest()

    破吧。

    0条评论 | 修改 | 链接
  • 小米娱乐 小米娱乐 1

    我有个方法不知道可不可行!!!
    先用 JavaScript MD5 将密码(为了提高安全也可以 “密码+用户名”)在本地加密,
    然后通过JavaScript截取中间的20位提交到服务端,就算别人半路截取了,也只有其中的20位,
    想推断出原始密码还是蛮有难度的!!!

    其次就要判断这些数据是来自页面传递还是来自工具传递!!尽可能的增加安全性!!

    小米娱乐 1

    0条评论 | 修改 | 链接
  • thean thean 0

    A=(ID+MD5(pwd)+mac+rand)
    B=rsa(A)
    C=ID+B+A(ID+MD5(pwd))

    0条评论 | 修改 | 链接
  • ThreeZhiWang ThreeZhiWang -11

    单纯从密码学角度来讲。
    MD5完全可以。
    MD5的被攻破只不过是可以算出原值区间。
    而且已有的MD5比较表无非就是算出一些常用值罢了。
    非常用还无法破解。
    SHA1就更安全些。
    而且明文存储用户密码就是对用户的不负责。
    将密码HASH之后。
    可以保证网站无需记录用户密码。
    即使密码库泄露。
    也无法还原出用户密码。
    还原出只是那些常用密码。
    woaiXXX那种密码都是很难还原出来的。
    而且就算知道HASH值。
    依然无用。
    以上仅从密码学观点出发。

    0条评论 | 修改 | 链接
  • bastengao bastengao 80

    此文应该能给你一些答案。 http://coolshell.cn/articles/2078.htm...

    0条评论 | 修改 | 链接
  • P酱 P酱 135

    这次泄密事件首先反映的是应用程序或者说加密数据储存方由于这样那样的“理由”,安全保护不利所暴露的问题。明文保存显然是可悲而且可怕的措施,选取合适的非对称加密方式并储存加密结果仅用于比对是必须的。现在网上的md5暴库数据样本其实已经不小了,所以一般尽可能要对原始密码做变换后在做hash。
    考虑到服务器性能问题,连续多次hash并不十分推荐(实际上按现有的暴库能力,两次合理的hash已经能非常有效地提升保密性能了)。
    而hash之前使用基于用户的单一salt(比如用户名或者注册时间戳或者前面
    Charlie Jade 提到的每次登陆更新的随机salt)对明文密码进行加盐混淆是相当有效的。
    为减低冲撞,用特定字符串补齐长度至比如32位后再进行hash也是不错的主意。

    0条评论 | 修改 | 链接
  • 高成 高成 1

    两个方面的问题怎么加密?怎么存储?加密简单,肯定可以弄个不容易破解的,但是还要想想到时候用户登录的时候怎么验证的问题既怎么存储!

    0条评论 | 修改 | 链接
  • ivens ivens 1

    前端js加随机 salt进行MD5后传输,外加https(条件允许和根据实际场景),后端存储的时候再次加上随机salt后md5,基本能满足需求了。

    0条评论 | 修改 | 链接