【总结2】注册与登录:用户密码加密的设计

本问题对应的项目链接:从0设计一个web项目
要求:已经完成阅读的,打卡一下哈,你可以进行凝练总结,或者就说 已完成阅读 也行

大家好,我是帅地。

关于用户密码加密这个事情,打卡区里有两位同学都给出了不错的想法(截止2022.7.29),相信不少做过项目的同学,加密都是采用 盐值+md5的,但现在这种方法不够安全了。本文的内容我们就来说一说关于加密的4个事。

1、为啥要加密 + 加密原则

2、普通方法为啥会被破解

3、常见的加密算法

4、拓展阅读。

1、为啥要加密+加密原则

为啥要加密,这个估计不需要我说,这两年也出现了一些公司数据库泄漏了,但是没有加密,很多用户的账户密码都裸露在网上了,这种不加密的公司,也是让人很迷。

其实对于一个密码,加密不仅仅是为了担心数据库泄漏了,还得防止被工作人员偷偷拿去卖或者自己偷偷登录了,所以呢,我们在加密的时候,还得让密码不可逆(所谓不可逆就是加密之后,就无法被还原了),这也是为啥密码忘记了,只能让你重置密码的原因,因为对方系统也不知道你的密码是啥。

因为密码可逆的话,工作人员是可以看你的加密代码,之后拿数据库的数据来还原,这样也就让你的密码暴露了,所以我们在加密的时候,是需要考虑

1、数据库泄漏

2、加密的代码逻辑也泄泄漏了

基于这两个假设来设计加密,才足够安全。

2、不可逆散列算法

加密的算法很多,比如对称加密,非对称加密,不过这些加密方式都是可逆的,比如密钥被人拿到了,那你就会被还原了,所以我们不能用这些,我们一般用MD5这种来加密,不过说实话,MD5严格来说不是一种加密算法,毕竟不能解密,算是一种散列算法,一般用于用户密码加密。

散列算法其实有好几种,比如 SHA 啥的,不过我们采用 MD5 来加密就行,不懂 MD5 的,自己搜索下哈。

3、如何加密才能难以被破解?

(1)早期的加密算法

其实在早起,大部分人都是直接用 MD5,比如对一个密码 password = 123456,进行 MD5 散列,即 MD5(“123456”) = 散列值,并且这个散列值长度高达 128 位。说实话,你要暴力破解,也很难,所以呢,在早期时,用 MD5 散列存放就可以了。

不过后面随着密码撞库以及彩虹表等的兴起,直接用 MD5 这种加密就不大行了。总的来说就是,我们可以维护一个密码库,这个密码库收集了用户的常用密码,比如像很多用户就喜欢用手机号码啊,邮箱啊等等,我们可以预先把密码库里的密码进行散列,之后直接拿数据库的散列值来匹配就可以了。

当然,彩虹表就比较复杂了,彩虹表主要用来解决数据过多的问题,比如说密码库非常非常大,这样就会占用非常多的空间,而用彩虹表,就可以减少空间,关于彩虹表的具体原理,你可以看文末的参考拓展阅读部分。

也就是说,随着破解方法的兴起,简单的加密已经无法很好保证密码的安全性了。

(2)盐值 + MD5

要想清楚我们的 MD5 加密之所以不行,是因为彩虹表,这种秘密库的出现,加快了破解的效率,那 要解决我们的问题,方法有两种:

1、让他们暴力破解起来的时间更加久,久到吓退它们。

2、让他们的密码库更大,大到难以维护。

所以呢,现在很多人用了 盐值 + MD5,简单说就是除了将用户的密码进行 MD5 外,我们自己在单独生成一个随机数,把这个随机数称之为盐值,然后把盐值和密码进行拼接,在进行MD5。

这样,可以在一定的情况下,让这种密码库碰撞变的更难,但是即使这样,也无法解决问题,因为你的盐值也一样泄露了,对方可以对于某一个用户,用他的盐值+拼接他的密码库,来进行碰撞,不过也算是加大了他们的难度,毕竟他们现在需要对某一个用户,都来进行这样的操作。

破解就需要时间,有时候密码泄露了,我们也不知道已经泄露了,而密码大家改的频率很低,所以迟早会被破解。

(3)PBKDF2算法与bcrypt、scrypt等算法

居然迟早会被破解,那我就让它100年后才能破解,于是出现了 PBKDF2算法与bcrypt、scrypt等算法,虽然这些算法看着很陌生,但是思想很简单,就是通过绕来绕去,增加他们破解的时间。

比如我们用 MD5 散列会因为撞库等原因被破解,那我们干脆就进行多次哈希散列,比如进行个上千次哈希散列,像 PBKDF2算法 就是采用这样的思想,而且我们不是简单让 盐值拼接密码来哈希散列,而是可以先对盐值或者密码啥的先进行散列,之后再拼接再散列值,在进行个 N 次散列。

这样就很难撞库,彩虹表也会非常非常大,对于我们服务器来说,进行上千次散列其实很快能完成,但是对方要暴力破解就会很难了,毕竟它也需要 模仿我们进行上千次散列。

也就是说,通过这种多次散列的方法,我们可以增加破解的难度,使得暴力破解需要很久很久很久才能破解成功,所以 PBKDF2算法 也是加密的常用算法。

当然,具体的算法逻辑肯定是比较复杂的,我这里讲的 PBKDF2算法 只是它的一个思想,不过大家了解下思想就可以了。

除此之外,scrypt 这些算法也是类似的思想,他们虽然不是进行很多次哈希,不过他们的算法特点是生成密码的过程很慢,比如调用一次 scrypt 算法,需要运行比较久才能得到结果,本质也是增加他们的破解时间。

所以 script 也是一种不错的防御方式。

所以以上几种便是我们采用的方法,多次哈希或者密码生成尽可能慢。

拓展阅读

关于彩虹表,大家可以看这篇文章最后一部分:常见的用户密码加密方式以及破解方法

然后如果要了解更加具体的彩虹表算法,可以看这篇:什么是彩虹表?

共以下 7 个回答

  • 星河揽我入梦 永久会员 2024年7月8日 上午10:57

    已完成阅读

    0 赞同 0 条回复
  • So 普通 2022年11月2日 下午2:17

    已完成阅读

    0 赞同 0 条回复
  • 豆子彩虹 普通 2022年10月27日 上午11:30

    已完成阅读

    0 赞同 0 条回复
  • lucca 普通 2022年10月9日 上午2:30

    已完成阅读

    背景

    无法完全阻止数据泄露,重心转为泄露了也无法破解
    也就是实现无法破解或破解成本大(巨大的时间空间成本)

    设计前提

    1.数据库有可能泄露
    2.加密方法有可能泄露

    加密原则:不可逆

    只要你猜不到,就只能继续猜,不能靠结果倒推

    加密思路

    多次不可逆加密(破解时间成本升高) + 加比较复杂的盐(破解空间成本高)

    常见算法

    • 可逆:对称,非对称(保存密钥困难,不推荐)
    • 不可逆:
      1. 单hash:md5,sha(彩虹表可破解,不推荐)
      2. PBKDF2(类比md5多次)
      3. bcrypt,scrypt(破解难度大,推荐)

    彩虹表:暴力枚举表空间压缩版

    使用记录一条计算链首尾的方式来存储一条链
    1 -> hash1 -> 2 -> hash2 -> 3 -> hash3
    通过hash函数计算hash(1->hash1),还要设置一个函数把hash映射回解空间(hash1->2)
    当一条数据经过n次计算后能够和某条链的尾匹配,那么它就在这条链
    从头再计算一遍,期间得到指定的hash,就能倒推原值
    为了减少重复数据,把每一次从hash映射回解空间的函数都设置的不一样,像彩虹一样,故称彩虹表

    0 赞同 0 条回复
  • Second(S) 普通 2022年10月2日 下午9:43

    已完成阅读

    0 赞同 0 条回复
  • 小肸 永久会员 2022年9月30日 下午3:10

    已完成阅读

    0 赞同 0 条回复
  • 秊 永久会员 2022年9月30日 下午12:56

    已完成阅读

    0 赞同 0 条回复

# 回答此问题

后才能回答