最近听闻 @callmewhy 同学因为此问题和某某同学争论不休,不惜大吵一架,特地把此略显纠结的问题放到此处,欢迎各位大牛来喷?
简单说下当时吵架的缘由(来自 @callmewhy 的回答)。
起因是一个90后团队搞的一个流氓公司,做 Mac 下的盗版应用商场,被大别骂了一通,同时调侃 http 协议明文传输用户名密码,太低级。后来有个人站出来,提出“前端对数据进行加密没有意义”这个观点。
(只谈技术)
最近听闻 @callmewhy 同学因为此问题和某某同学争论不休,不惜大吵一架,特地把此略显纠结的问题放到此处,欢迎各位大牛来喷?
简单说下当时吵架的缘由(来自 @callmewhy 的回答)。
起因是一个90后团队搞的一个流氓公司,做 Mac 下的盗版应用商场,被大别骂了一通,同时调侃 http 协议明文传输用户名密码,太低级。后来有个人站出来,提出“前端对数据进行加密没有意义”这个观点。
(只谈技术)
加密不等于混淆,加密的文本需要解密得到原文,而混淆则不需要。如果问题改成 http 下提交登录密码时是否需要混淆,那么答案是肯定的:”是,建议这么做。“但这和这个问题讨论的内容就有些偏差了。
有时间折腾前端加密,还不如去买一个 https 证书,靠算法加密的代码只是自欺欺人。
对于文中提到的实际案例,用明文传递 Apple ID 和密码,这种情况下密码是必须以可逆加密传输到服务器的,所以监听者一定是有办法解密的,几乎没机会防住。
如果真的想让前端加密有意义,那就像 SSL 一样通过非对称加密并且一次一密的方式和服务器交互,但是都愿意这么折腾了,为什么还不用 https?一个证书也就 300 元,在帝都也就是一个前端开发工程师半天的工资而已。
所以,前端折腾加密真心没用,在意安全性的人会用 https,不在意的人随他去吧。
不加密的话如果HTTP请求被拦截的话就可以知道用户的原始密码了,这是一件要不得的事情。于你网站本身来说,这个问题应该不大,因为如果被拦截了,不管怎样拦截者只要查看源码,模拟请求之后都能登陆上。但是因为很多用户目前来说基本上来说不会一个网站一个密码,而是对应着多个账户的。所以如果知道了用户的原始密码,结合社会工程学,能干的事情就挺多了。
特意看了下,sf都是直接post明文的。
http是不安全的,即使在一些不重要的网站,密码还是应该要加密的,毕竟现在有一种东西叫社工库。
不过真要保证传输安全的话md5都已经不靠谱了,还是要采用一些更加复杂的算法,但是这样会加大密码验证系统的复杂性。
我简单说下当时吵架的缘由。
起因是一个90后团队搞的一个流氓公司,做 Mac 下的盗版应用商场,被大别骂了一通,同时调侃 http 协议明文传输用户名密码,太低级。后来有个人站出来,提出“前端对数据进行加密没有意义”这个观点。
后来就是我们的骂战了。。。
我不否认他的观点,确实前端加密对于真正下定决心黑的hacker而言形同虚设,但是在这个例子里,明文传输的是第三方的密码:Apple ID 与密码。在此,我认为加密是有必要的。因为这个是用户在另一个网站的数据,如果加密之后,虽然攻击者可以通过重放攻击重新进行登录,但是加密情况下无法获取到原始的 Apple ID 的账号和密码。所以“前端加密无用”的论点我认为在这个例子里并不适用。
可惜他完全不理会。。。我觉得和一个不思考的人吵架没什么意思,就把他拉黑了。
我觉得加密和安全,不是为了完全阻挡攻击,而是为了提高攻击的成本,降低被攻下的概率。
后来想到“前端加密无用”这个结论,这个论点且不谈一些特殊的情况(比如传输银行密码),光说用户登录,前端加密是否真的无用呢?
假设我们依旧用 http ,如果在加密的字符串中加入当前时间戳,在服务器解密的时候校验时间戳,这样的情况下,前端加密是不是就有用了?
当然还是用 https 这个没的说,只是单纯想讨论下这个问题、、
前端对数据进行加密当然没有意义,不管你怎么加密,攻击者都可以用重放达到目的(伪造用户登录而不是拿到用户名和密码)。
我司的登录用的就是http明文,密码加了一层薄薄的md5 hash。呵呵。
我觉得没有必要。要防中间人就直接上 https 嘛,简便快捷。
不过这类前端加密也不是全无好处。
假设在 http 时,使用前端加密:如果是对称加密的话,中间人花点心思就可以推算出来;如果使用非对称加密的话,还不如直接 https。不过对于广撒网的脚本小子来说,不能直接得到明文确实可以抵挡一些泄露。
话说这不是老生常谈的问题了吗?既然中间人存在的话,那么肯定得使用非对称加密。加个 https 证书的成本比自己在前端做要方便多了。这类全端加密方案作为一个免费方案但不如 https 普及的原因不在于性能不在于技术难度,就在于实在麻烦。
使用自己的登录控件,比如支付宝,财付通,各银行等。
还有个某公司的键盘芭蕾的也是要客户安装控件,据说还会记录用户按键的时长和间隔,通过这两项值来验证密码是不是用户输入的,也就是有了密码也不一定能登录。当然这需要事先采集多次用户输入。 说的挺牛逼的,具体就不得而知了。
我看到过一种处理方法,大致如下:
通过session计算出一个常数,储存在服务器。
在提交password的时候,在前端通过js将这个常数与用户输入的密码进行md5运算,运算结果POST给服务器。
服务器这边从数据库取出密码,同样的步骤在服务器端运行一次。
两次结果做比较。
有一个缺点就是服务器需要明文储存密码
登录注册还是用https安全。
在客户端base64或者md5什么的真心没用,我直接监听到你所谓的密文,然后用脚本发起一个http请求就可以登录上去了。
http在网络上是明文传输的,代理和网关都能够看到所有的数据,在同一局域网内也可以被嗅探到,你可以开个wireshark抓下局域网的包试试看。
刚看了@callmewhy 的回答,我认为加密也没有提高什么攻击难度,因为攻击者就没必要去解密原始密码,能登录上去就表示目标已经实现了,所以,难度没有提高。
另外,在客户端md5后,服务端怎么把原始密码还原出来,不能数据库直接存md5吧?
所以要选择加密算法的话,还要让服务端能还原出来原始密码。
然后:
如果是简单的base64下,这种算法对安全性没什么提高呀,base64又不是加密算法,它的作用就是编码下而已,如果这个能难道黑客的话,那他可以洗洗睡了。
其他的诸如非对称加密之类的算法当然可以,但是这不是https提供的功能么?而且https提供的安全保障还可以应对其他的攻击。
看,饶了一圈又到这里了,唯一可靠的还是https,所以别吵了,买个证书切上https睡觉去吧。
----------2014-11-18 补充--------------
@straysh 不同意您的说法。
如果用https加载的页面,这个页面又加载了普通的http资源,如果有中间人的话,他监听不到https请求的信息,但是可以监听或篡改这些走http的请求信息,进而可以进行注入js脚本等。
您所说的,并不能证明https不安全,只是说明了https里加载的http资源这种方式不安全,属于错误使用范畴,这种情况下正常点的浏览器都会发出警告了。
不好意思,E文的刚没仔细看,说的不是一个问题囧。。。证书问题确实没办法,全靠浏览器厂商了。
加密了也无法解决重放的问题,你发给服务器端的虽然是加密后的数据,但是黑客拦截之后,吧加密之后的数据重发一遍,依然是验证通过的。
再者,既然是加密,那么加密用的密钥和算法肯定是保存在前端的,攻击者通过查看源码就能得到算法和密钥。除非你是通过做浏览器插件,将算法和密钥封装在插件中,然后加密的时候明文混淆上时间戳,这样即使黑客拦截到了请求数据,进行重放过程时,也会很快失效。
一个比较保险的做法是,通过https协议提交登录数据,这样黑客抓包时得到的数据是加密的,而且无法反解。
登录注册,https是必要的;
若需要防重放,则再加一个一次性令牌参数;
看你的需求和场景了,要不要做到这么高的安全性;
如果不想弄https,那就要把所有参数做RSA加密再传输;这也能做到和https一样的安全性,本身https做的事情也不过如此
我同意@沙渺 和 @callmewhy 的观点:
技术是个有梯度的东西。
防护措施是一定要有的,仅仅前端MD5后post也不失为一种方案。
没有什么加密是100%安全的(see How secure is HTTPS today? How often is it attacked?),不能因为安全度不够就完全放弃安全防护吧(态度问题吧,这种做事的态度做不出高质量的东西)。
如果真的关注安全问题的话就上https。至于http前端有没有加密的必要,有,加密当然比明文强,有胜于无嘛。
楼上已经说过,大部分用户都是一个用户名和密码在很多站上用,不能因为http没法抵挡对你网站的重放就让中间人有了获取用户其他网站登陆密码的可能,你需要对你的用户安全负责。
楼上不赞成加密的大多都是觉得加密了也能还原密码,简单的base64很明显,md5也是常用密码可以字典得到。
下面是我用的方式,和楼上某位讲的有些类似。
加密盐,防止md5值被逆向。
salt = "网站自定义的一个加密盐",服务端和客户端都有该值。
注册的时候对密码加盐做散列vp = md5(密码明文+salt),保存到数据库。
登陆:
服务器端产生一个随机值rnd保存在服务器的session里面,并传给浏览器;
浏览器提交加密过的密文:md5(md5(密码明文+salt)+rnd)
服务器验证的时候从数据库读出注册时候保存的散列值vp,做运算md5(vp+rnd),和浏览器提交的密文做比较。
这样至少可以让服务器不保存密码明文也能防止暴库之后被逆向,同时登陆过程中提交的密文也基本没法还原。因此中间人只能抓取会话,重放会话,会话过期之后也没法重放了。
最后,为了安全还是上https。
加密的话,虽然截取不到明文,但是你服务器接受表单参数的时候接收的也是密文。这样一来截取到的密文和明文具有相同的效力。
而https不同,服务器接收之后自动由底层解密,再解析。它是整体加密的,你根本不知道哪一部分起什么作用。
我認爲 https 下纔有加密登錄密碼的意義。
http 下根本不應當以任何形式傳輸登錄憑據。只要傳輸了,怎麼保護都沒用。
在 https 下需要加密登錄密碼的理由:有些 SSL 的漏洞只會暴露明文而無法修改,比如 heartbleed。
在 http 下加密毫無意義的理由:基本上能看到就能修改。能修改,能修改!能修改你還加密個毛,進攻方直接返回一個假的網頁不就得了,想隱藏地深一點,那就先竊取密碼,再模仿原程序加密提交唄。
http 下加密和不加密基本沒區別,就像沒經過 CA 驗證的 SSL 一樣。加密傳輸的本質是信任,可要想有所信任,先得有所信任。http 下無所信任,也就不可能存在實質上的加密傳輸。只是看上去能給人一種並不存在的安全感罷了。
其实加不加密并没有什么用,因为同一个密码,每次登录传输的密码字段是不一样,每次传输的密码字段一样的,加密和不加密有什么区别
除非你用户注册就生成自己的证书,用户更改密码,登录账户,都重新生成证书,客户端通过证书加密,发送到服务器,服务器根据客户端的加密数据,与用户自己的证书匹配,不正确提示密码错误,正确登录成功,生成新的证书保存到数据库
8 回答4.6k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
6 回答2.3k 阅读
5 回答6.3k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
有。
技术是个有梯度的东西。一个浅显的base64编码尚且已经够挡住很多菜鸟了,客户端单向加密一下虽然不能抵抗重放攻击,但至少这也能防住用户的所有密码在你的网站单点暴死——毕竟多数人是多个网站同一密码的。
题外话:http就是不安全的代名词。密码重放攻击也许还可以通过实现握手协议来解决,但cookie伪造攻击却几乎无解。请开发者在有必要时务必尽可能采用https,请上网用户切记再懒也要给http网站和https的网站采用两套不同的密码。