乐趣区

关于java:面试官设计一个安全的登录都要考虑哪些我一脸

作者:letcafe

起源:https://www.cnblogs.com/letca…

1. 一个简略的 HTML 例子看看用户信息安全

规范的 HTML 语法中,反对在 form 表单中应用 <input></input> 标签来创立一个 HTTP 提交的属性,古代的 WEB 登录中,常见的是上面这样的表单:

<form action = "http://localhost:8080/Application/login" method = "POST">
    用户名:<input id="username" name="username" type="text" />
    明码:<input id="password" name="password" type="password" />
    <button type="submit"> 登陆 </button>
</form>

form 表单会在提交申请时, 会获取 form 中 input 标签存在 name 的属性,作为 HTTP 申请的 body 中的参数传递给后盾,进行登录校验。

例如我的账号是 user1,明码是 123456,那么我在提交登录的时候会给后盾发送的 HTTP 申请如下(Chrome 或者 FireFox 开发者工具捕捉,需开启 Preserve log):

能够发现即使 password 字段是黑点,然而本机仍以明文的模式截获申请。

2. HTTP 协定传输间接裸露用户明码字段

在网络传输过程中,被嗅探到的话会间接危及用户信息安全,以 Fiddler 或 Wireshark 为例,发现捕捉的 HTTP 报文中蕴含敏感信息:

3. 应用加密算法能保障明码平安吗?

WEB 前端能够通过某种算法,对明码字段进行加密后,在将明码作为 Http 申请的内容进行提交,常见的包含对称和非对称加密。

对称加密: 采纳对称明码编码技术,它的特点是文件加密和解密应用雷同的密钥加密。

非对称加密: 须要两个密钥,公开密钥(publickey)和公有密钥(privatekey)。公开密钥与公有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的公有密钥能力解密;如果用公有密钥对数据进行加密,那么只有用对应的公开密钥能力解密。

3.1 应用对称加密

加密解密在前后台协商后,仿佛是个不错的方法,比方,前台应用一个字符串位移 + 字符串反转的简略办法(举个例子,当然不能这么简略)。那么,如果原明码 123456 先移位:

123456-->456123

再进行反转:

456123-->321654

那么这样简略的办法仿佛能够混同原明码,并且轻松由后盾进行相同操作还原。然而这有两个毛病:

  1. 前后端加密解密须要同时批改代码;
  2. 前端加密无非是写在 JS 里,然而 JS 有危险被间接破解从而辨认加密办法。

3.2 非对称加密 HTTPS 就肯定是平安的吗?

非对称加密有着公钥私钥的存在,公钥能够随便获取,私钥是用来对公钥解密的本地存储,通过公私钥的机制仿佛能够保障传输加密并且乃至当初还在应用的 HTTPS 就是基于这个原理。
然而 HTTPS 就肯定平安吗?HTTP 存在两种可能的危险:

  1. HTTPS 能够保障传输过程中的信息不被他人截获,然而细细思考下,HTTPS 是应用层协定,上层采纳 SSL 保障信息安全,然而在客户端和服务端,密文同样是能够被截获的;
  2. HTTPS 报文在传输过程中,如果客户端被歹意疏导装置“中间人”的 WEB 信赖证书,那么 HTTPS 中的“中间人攻打”一样会将明文明码泄露给他人。

4. 论断是,无论 HTTP 还是 HTTPS,明码必须密文传输

想想 HTTPS 也不能肯定保障用户明码信息,那么就应该思考在应用层之上再持续对明码进行爱护,也就是编写代码来进行管制,而不依赖特定协定,比拟容易想到的就是利用不可逆加密散列函数 MD5(string),用户在注册输出明码的时候,就存储 MD5(password)值,并且在 WEB 端先进行 MD5(password),而后将明码传输至后盾,与数据库中的密文进行比拟(PS:MD5 函数在指定位数的状况下,对雷同字符串运算值雷同)。长处比拟显著:

  1. 保障了用户数据库外部的明码信息安全;
  2. 传输过程中无论如何都不会使得用户的密文被破解出原明码;
  3. 简略高效,执行以及编码难度都不大,各种语言都提供 MD5 反对,开发快。

5. 那太好了!这样能够省下 HTTPS 的钱了,真是这样吗?

回到结尾的例子:用户输出的用户名是:user1,明码是:123456,那么不论在什么协定之下,能够看到理论发送的 HTTP/HTTPS 报文在 MD5 解决后是这样的:

没错,加密登录胜利了。然而,当咱们庆贺明码平安的时候,发现账户的钱忽然不胫而走。这是为什么呢?黑客却笑的很开心:因为他们并不一定要获取到你的明码明文,如果间接截获你的明码密文,而后发送给服务器不是一样能够登录吗?因为数据库里的不也是 MD5(password)的一样的密文吗?HTTP 申请被伪造,一样能够登录胜利,从而夺取其余的数据或者转走余额。

这怎么办? 其实并不难,有很多种解决办法?其实原理都是相似的:那就是服务器缓存生成随机的验证字段,并发送给客户端,当客户端登录时,把这个一并字段传给服务器,用于校验。

5.1 计划一:验证码

MVC 场景。控制器将把数据的 Model 封装到 View 中,这种存在 Session 的连贯形式,容许了在 Session 中存取信息。那么咱们能够利用一些开源的验证码生成工具,例如 JAVA 中的 Kaptcha,在服务端寄存生成一个验证码值以及一个验证码的生成图片,将图片以 Base64 编码,并返回给 View,在 View 中解码 Base64 并加载图片,并于用户下次登录时再进行比对。

5.2 计划二:token 令牌

前后端拆散场景。当初十分风行的前后端拆散的开发模式大大提高了我的项目的开发效率。职责、分工明确,然而因为 HTTP 是无状态的(就是这一次申请并不知道上一次申请的内容),当用户登录时,依据用户的 username 作为 key,生成随机令牌(例如 UUID)作为 value 缓存在 Redis 中,并且将 token 返回给客户端,当客户端登录时,将实现校验,并且删除 Redis 中的那条缓存记录。

那么每次从服务器中获取认证的 token,的确能保障 HTTP 申请是由前端传回来的了,因为 token 在每次登陆后都会删除并被重置,会导致黑客尝试重放账号密码数据信息来登陆的时候导致无奈胜利登陆。

总而言之,就是我拿到了账号以及明码的密文也登陆不了,因为,如果申请不蕴含后盾认证的令牌 token,是个非法申请。

6. 太不容易了!可是还别快乐的太早,当心数据被篡改

明码也加密了,黑客看不到明文了。加上 Token 了,登陆过程也没法再被截获重放了。可是想想这种状况,你在进行某宝上的网络领取,须要账号,明码,金额,token 这四个字段进行操作,而后领取的时候你付了 1 块钱买了一袋包邮的小浣熊罗唆面,某宝结算完结后,你发现你的账户余额被扣了 1 万元。这又是怎么回事呢?

因为即使黑客不登录,不操作,一样要搞破坏:当申请路由到黑客这边的时候,截获数据包,而后也不须要登录,反正账号密码都是对的,token 也是对的,那么把数据包的字段改改,搞破坏就能够了,于是把 money 改成了 1 万,再传给服务器,作为受害者就莫名其妙踩了这个坑。可这该怎么解决呢?其实原理相似于 HTTPS 里的数字签名机制,首先科普下什么是数字摘要以及数字签名:

6.1 什么是“数字摘要”

咱们在下载文件的时候常常会看到有的下载站点也提供下载文件的“数字摘要“,供下载者验证下载后的文件是否残缺,或者说是否和服务器上的文件”截然不同“。其实,数字摘要就是采纳单项 Hash 函数将须要加密的明文“摘要”成一串固定长度(128 位)的密文,这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其后果总是不同的,而同样的内容信息其摘要必然统一。

因而,“数字摘要“叫”数字指纹“可能会更贴切一些。“数字摘要“是 HTTPS 能确保数据完整性和防篡改的根本原因。

6.2 数字签名 – 瓜熟蒂落的技术

如果发送方想把一份报文发送给接管方,在发送报文前,发送方用一个哈希函数从报文文本中生成报文摘要, 而后用本人的私人密钥对这个摘要进行加密,这个加密后的摘要将作为报文的”签名“和报文一起发送给接管方,接管方首先用与发送方一样的哈希函数从接管到的原始报文中计算出报文摘要,接着再用发送方的专用密钥来对报文附加的数字签名进行解密,如果这两个摘要雷同、那么接管方就能确认报文是从发送方发送且没有被脱漏和批改过!这就是联合“非对称密钥加解密”和“数字摘要“技术所能做的事件,这也就是人们所说的“数字签名”技术。在这个过程中,对传送数据生成摘要并应用私钥进行加密地过程就是生成”数字签名“的过程,通过加密的数字摘要,就是”数字签名“。

因而,咱们能够在 WEB 端对之前案例中提到的 username+MD5(password)+token 通过签名,失去一个字段 checkCode,并将 checkCode 发送给服务器,服务器依据用户发送的 checkCode 以及本身对原始数据签名进行运算比对,从而确认数据是否中途被篡改,以保持数据的完整性。

7. 总结

看似非常简单的 WEB 登录,其实外面也存在着十分多的安全隐患。这些平安欠缺的过程是在一个理论 WEB 我的项目中遇到的,下面的剖析演变是在应答我的项目平安的查看中所提出的解决方案,多少会有很多有余的中央,心愿一起交换探讨,共同进步!

补充 1:JS 加密函数存在被破解

感激园友 mysgk 指出完整性测验中对于 JS 加密函数存在被破解的问题:

问题形容:

如果黑客通过浏览前端 js 源码, 发现加密算法, 是否象征他能够结构能够
被服务端解密的 checkCode 来坑骗服务端呢 ?

我想了下,应该也是很多网站也在采取的策略:

摘要或加密 JS 算法不间接以动态文件的模式存在浏览器中,而是让 WEB 端去申请 Server,服务器能够依据随机令牌 token 值决定返回一个相应随机的加密策略,以 JS 代码响应的形式返回,在异步申请响应中,加载 JS 摘要算法,这样客户端就能够动静加载数字摘要策略,保障无奈仿造。

补充 2:MD5 存在隐患的问题

感激园友 EtherDream 提出 MD5 曾经过期,并且存在不平安的问题:

问题形容:

用 MD5、SHA256 解决明码的过期了。。。当初 PBKDF、bcrypt 都在过期中。

  1. 本文重点侧重于办法思路的介绍,并不一定是要应用 MD5 函数,能够应用其余的形式。
  2. MD5 存在隐患,之前的确没有思考太多,不过非常感谢园友指出,的确是这样的,次要思维是:

对于 MD5 的破解,实际上都属于【碰撞】。比方原文 A 通过 MD5 能够生成摘要 M,咱们并不需要把 M 还原成 A,只须要找到原文 B,生成同样的摘要 M 即可。
设 MD5 的哈希函数是 MD5(),那么:
MD5(A) = M
MD5(B) = M
任意一个 B 即为破解后果。
B 有可能等于 A,也可能不等于 A。

大略意思也就是,截获了 MD5 加密后的密文,一样能够,找到一个不是原明码,然而加密后能够登陆胜利的“伪原文”。

从中能够看到一点,MD5 函数的确能被反向“破解”,然而这个“破解”只是找到一个通过 MD5 运算后失去雷同后果的原文,并非是用户的明文明码。然而这样会被破解登录的可能,的确是须要采纳更欠缺的算法进行加密,再次感激!

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2021 最新版)

2. 别在再满屏的 if/ else 了,试试策略模式,真香!!

3. 卧槽!Java 中的 xx ≠ null 是什么新语法?

4.Spring Boot 2.5 重磅公布,光明模式太炸了!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版