1. 一个简单的HTML例子看看用户信息安全
标准的HTML语法中,支持在form表单中使用标签来创建一个HTTP提交的属性,现代的WEB登录中,常见的是下面这样的表单:
<form action = "http://localhost:8080/Application/login" method = "POST"> 用户名:<input type="text" /> 密码:<input 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报文中包含敏感信息:
WEB前端可以通过某种算法,对密码字段进行加密后,在将密码作为Http请求的内容进行提交,常见的包括对称和非对称加密。
对称加密:采用对称密码编码技术,它的特点是文件加密和解密使用相同的密钥加密。
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
3.1 使用对称加密加密解密在前后台协商后,似乎是个不错的办法,比如,前台使用一个字符串位移+字符串反转的简单方法(举个例子,当然不能这么简单)。那么,如果原密码123456先移位:
graph LR 123456-->456123再进行反转:
graph LR 456123-->321654那么这样简单的方法似乎可以混淆原密码,并且轻松由后台进行相反操作复原。但是这有两个缺点:
前后端加密解密需要同时修改代码;
前端加密无非是写在JS里,但是JS有风险被直接破解从而识别加密方法。
3.2 非对称加密HTTPS就一定是安全的吗?非对称加密有着公钥私钥的存在,公钥可以随意获取,私钥是用来对公钥解密的本地存储,通过公私钥的机制似乎可以保证传输加密并且乃至现在还在使用的HTTPS就是基于这个原理。
但是HTTPS就一定安全吗?HTTP存在两种可能的风险:
HTTPS可以保证传输过程中的信息不被别人截获,但是细细思考下,HTTPS是应用层协议,下层采用SSL保证信息安全,但是在客户端和服务端,密文同样是可以被截获的;
HTTPS报文在传输过程中,如果客户端被利用引诱安装装了“中间人”的某种证书,那么HTTPS中的“中间人攻击”一样会将明文密码泄露给别人。
4. 结论是,无论HTTP还是HTTPS,密码必须密文传输想想HTTPS也不能一定保障用户密码信息,那么就应该考虑在应用层之上再继续对密码进行保护,也就是编写代码来进行控制,而不依赖特定协议,比较容易想到的就是利用不可逆加密散列函数MD5(string),用户在注册输入密码的时候,就存储MD5(password)值,并且在WEB端先进行MD5(password),然后将密码传输至后台,与数据库中的密文进行比较(PS:MD5函数在指定位数的情况下,对相同字符串运算值相同)。优点比较明显:
保证了用户数据库内部的密码信息安全;
传输过程中无论如何都不会使得用户的密文被破解出原密码;
简单高效,执行以及编码难度都不大,各种语言都提供MD5支持,开发快。
5. 那太好了!这样可以省下HTTPS的钱了,真是这样吗?回到开头的例子:用户输入的用户名是:user1,密码是:123456,那么不管在什么协议之下,可以看到实际发送的HTTP/HTTPS报文在MD5处理后是这样的:
没错,加密登录成功了。但是,当我们庆祝密码安全的时候,发现账户的钱突然不翼而飞。这是为什么呢?黑客却笑的很开心:因为他们并不一定要获取到你的密码明文,如果直接截获你的密码密文,然后发送给服务器不是一样可以登录吗?因为数据库里的不也是MD5(password)的一样的密文吗?HTTP请求被伪造,一样可以登录成功,从而攫取其他的数据或者转走余额。