前端加密

前端加密

注意:这篇文章是2016年的,如今已经过去6年,文中所说的HTTP协议大多已经换成HTTPS协议。

前端传输的数据我们应该用什么算法加密,如何组织整个加密过程呢? 一般有几种做法:

  • JavaScript 加密后传输
  • 浏览器插件内进行加密传输
  • Https 传输

在这里其实 HTTPS 是终极解决方案,所以文章对于仍在使用 HTTP 建站的小伙伴更有帮助。本文中将讨论第一种方法,也就是使用 JavaScript “加密”。使用双引号是因为这里面分为两种手段,一是使用数据摘要进行消息杂凑,二是使用非对称加密算法对明文进行加密

严格意义来说第一种手段并非加密,而是一种信息摘要的应用,为了阐述方便下文统统使用加密一词。

哈希与加密

preview

上图中我们可以明显看到哈希和加密是两个不同的东西,主要有两点不同:

  • 哈希算法通常用于数据摘要,生成相同长度的文本。而加密算法生成的密文长度与明文长度有关。
  • 哈希算法是不可逆的,而加密算法是可逆的。

在加密算法中又分为对称加密(symmetric encryption)和非对称加密(asymmetric encryption)。非对称加密算法中,加密密钥和解密密钥是不同的,分为私钥和公钥,我们熟知的 RSA 就是一种非对称加密算法。而对称加密中,加密和解密都是用同一个密钥,如 AES / DES。从性能上来说,非对称加密相对于对称加密要慢很多。在 HTTPS 中,认证过程使用了非对称加密算法,非认证过程中使用了对称加密算法。

前端加密的意义

在 HTTP 协议下,数据是明文传输,传输过程中网络嗅探可直接获取其中的数据。 如用户的密码和信用卡相关的资料,一旦被中间人获取,会给用户带来极大的安全隐患。另一方面在非加密的传输过程中,攻击者可更改数据或插入恶意的代码等。HTTPS 的诞生就是为了解决中间人攻击的问题,但如今 HTTPS 的使用情况在国内并不乐观,基本是因为成本或者性能的考量。

Q:那么问题来了,如果仍然使用 HTTP 协议怎么样一定程度保证用户的数据安全?
A:前端加密,即在数据发送前将数据进行哈希或使用公钥加密。如果数据被中间人获取,拿到的则不再是明文。

设想在如今公共 WIFI 流行的今天,一旦某一个 AP 的流量被攻击者劫持,如果密码和用户名都是明文,那么攻击者将轻而易举的使用这些资料进行 Replay 登录。更糟糕的是很多用户在不同的网站使用相同的账号信息,用户的隐私荡然无存。作为网站服务提供者,网站设计和开发人员应该为用户提供相对安全的服务,这是一种责任也是一种情怀。

另外如果前端使用哈希算法,不仅可以帮助后端分担部分计算压力,还可以增加撞库成本。

如何加密

前面说过使用 JavaScript 加密有两种方式,一是使用哈希进行信息摘要,一种是使用非对称加密。在国内的知名站点中,这两种方式都有人使用。接下来我们分别来深入了解加密过程,探讨下如何应对不同的场景。

哈希“加密”

为了避免传输过程中的明文风险,前端可以在发送敏感数据前对其加密,如密码。由于哈希算法的不可逆性,中间人无法从截取的数据中得知用户的密码信息。但是这里有一个问题,攻击者仍然可以使用拿到的哈希值进行直接登录。使用前端加密如何避免中间人重放攻击?带着这个问题,我们回顾下后台如何验证用户。

很多站点后台对于用户密码处理也是用哈希算法,一方面因为不需要将密文解密成明文来比对密码,另一方面是一旦加密算法和密钥泄露,那么整个用户资料库就相当于明文存储了。如果前端传过来的是明文,那么在注册时将其哈希,存入数据库。登录时,将密码哈希和数据库对应的数据比对,若一致则说明密码正确。

如果我们使用 Salt 是否可以解决问题?如果前端传过来的是加了 salt 的哈希值,我们需要后端存有同一份 salt ,用其和数据库的加密密码哈希,然后与前端传过来的哈希值比对。两个过程的对比见下图:

preview

很容易知道,如果 Salt 不是每次登陆不同,那么攻击者仍可以使用加密后的密码进行直接登陆,所以必须使用动态 Salt。动态 Salt 有很多方法,可以是动态的 Token,也可以直接使用现成的验证码。 这当中使用验证码是对后台系统改动较小且效果不错的,我们来看看怎么样结合验证码进行前端加密。

结合验证码进行前端加密

前端先将密码哈希,然后和用户输入的验证码进行哈希,得到的结果作为密码字段发送给服务器。服务器先确认验证码正确,然后再进行密码验证,否则直接返回验证码错误信息。

Hash

这种实践保证了密码在传输过程中的资料安全,即使攻击者拿到了数据也无法重放。图形化验证码更是增加了难度。另一方面该实践大大增加了撞库的成本。

前端加密一定程度保障了传输过程中的资料安全,那么会不会有对两端(客户端和服务器)有安全帮助呢? 有帮助,使用一些前端加密手段,可以增加拖库后的数据破解难度。但是之前介绍的验证码方法不具有这样的功能,因为数据库存的仍是明文密码哈希后的结果,那么攻击者可以绕过前端加密,可以直接暴力破解。

如何增加拖库后的数据破解难度

使用怎么样的前端加密方法可以增加拖库后的数据破解难度?从两个方面分别去思考,一是降低破解速度,二是需要前端加密结果影响数据库的数据存储。数据被暴力破解出来的时间与哈希算法速度负相关。

我们知道暴力破解即是使用相同的算法把常用的字符组跑一遍,如果结果相同那么就猜中明文了。如果算法越快,便能更快的破解。例如 MD5 加密一次耗费1微秒,那么攻击者一秒钟就可以猜大约 100万个词组。所以为了减慢破解速度,我们需要增加破解的时间,一个直接的方法就是使用更慢的算法,我们可以把常用的MD5算法替换为 bcrypt,PBKDF2 等慢算法。

对于需要前端加密结果影响数据库的数据存储,即为后端加密把前端加密结果当做明文密码,那么存在库里的密码便是前端哈希加上后端加密的结果。由于慢的算法会增加服务器计算压力,当我们把一部分哈希工作拿到前端,即减慢了加密速度,减轻了服务器压力,也顺带完成了前端加密的工作。

加密速度减慢一定程度会降低用户体验,这也是一部分站点未启用 https 的原因之一。但是因为我们的前端加密只会用在不常使用的登录和注册上,所以不会影响网站整体的体验。

综上,我们可以使用更慢的算法,加之视前端哈希结果为明文密码,便可增加拖库破解的成本。既然增加了破解的成本,撞库的成本也同样增加了。为了避免攻击者先前使用前后端加密生成的新字典,我们需要加盐,并不定期更新盐值。下图文是使用过期 Salt 的方法描述:

Hash

前端加密使用定期刷新的 Salt,哈希后生成密文,再经过后端加密后即为用于比对的密文。数据库中的密码哈希值跟着 Salt 进行变化,前后端需要有一套salt的更新机制。

回顾前端哈希的方法,解决了中间人攻击重放、加大了拖库破解的难度。虽然这些方法都不能完全保证用户安全,但是作为站点服务者,应该视用户为上帝嘛。这些方法也不过就是几行代码的事,但是却能一定程度的避免了用户账号被盗等风险。

非对称加密

上文中我们讨论了前端的哈希加密以及应用的场景。对于十足的安全控来说,这样的措施对于有心的攻击者基本没有用。那么我们可以采用更强的措施保障传输中的敏感数据安全。

之前有说过加密算法分为对称加密和非对称加密,因为前端的透明性,使用JavaScript来进行对称加密是不可能的了,那么只剩下了非对称加密这个选择。

实现非对称加密也有两种方案:

方案一

如果用非对称加密,客户端的数据通过公钥加密,服务端通过私钥解密,客户端发送数据实现加密没问题。客户端接受数据,需要服务端用公钥加密,然后客户端用私钥解密。所以这个方案需要两套公钥和私钥,需要在客户端和服务端各自生成自己的密钥。

img

方案二

如果把对称加密和非对称加密相结合。客户端需要生成一个对称加密的密钥 1,传输内容与该密钥 1进行对称加密传给服务端,并且把密钥 1 和公钥进行非对称加密,然后也传给服务端。服务端通过私钥把对称加密的密钥 1 解密出来,然后通过该密钥 1 解密出内容。以上是客户端到服务端的过程。如果是服务端要发数据到客户端,就需要把响应数据跟对称加密的密钥 1 进行加密,然后客户端接收到密文,通过客户端的密钥 1 进行解密,从而完成加密传输。

img

总的来看,方案一比较简单,但是需要维护两套公钥和私钥,当公钥变化的时候,必须通知对方,灵活性比较差。方案二相对方案一来说,密钥 1 随时可以变化,并且不需要通知服务端,相对来说灵活性、安全性好点并且方案二对内容是对称加密,当数据量大时,对称加密的速度会比非对称加密快。我们的HTTPS协议就是用类似方案二的加密方法。。

参考资料

前端敏感数据加密方案及实现

当我们在谈论前端加密时,我们在谈些什么

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇