我们在做用户注册或登录模块时经常会遇到需要传输用户密码到服务端的问题,密码这类的信息在安全重要性上不言而喻,若在客户端,网络或服务端任何一个地方出问题被泄漏了密码则会产生严重的后果,就像下面一个简单的管理员登录的用户名和密码表单:
当我们打开chrome的network查看请求时
哇,我们的系统开天窗了,用户的所有请求在客户端浏览器上可以被正确的解析,我们的网络传输过程也可以被轻易的拦截,那我们的密码是否很不安全?那其实要解决这个问题也并不是很难,我们就来看一下如何安全的传输你的密码
数据加密
想要安全的传输,最重要的也是唯一的解决方案就是加密,就好比以前苏联和德国世界大战,双方互相借助通信力量拦截情报,加密情报,反解密情报等。安全通信的本质其实就在于你的加密是否足够强大。通用意义上的加密技术分为哈希散列,对称加密和非对称加密三种。
哈希散列
哈希散列并不能算是严格意义上的加密技术,因此我把它称为通用意义上的加密技术,哈希散列的通用定义是:通过一些不可逆的哈希算法将原本的明文内容转化为散列后的密文内容。 由于散列算法几乎不可逆,因此攻击者几乎无法通过密文猜测到对应的明文内容。通过这种机制做到加密控制,典型的算法由我们之前耳熟能详也就是课程内用到的md5加密算法。对应的加密方式代码实现已经上传到git文件夹安全传输密码MD5Util上这种加密算法有个非常大的隐患,就是对于若口令的攻击特别容易被破解,比如我对应的的用户明文密码是
明文密码=123456
使用md5加密后的密文
密文密码=e10adc3949ba59abbe56e057f20f883e
这代表了啥?所有密文是上面的字符串说明口令都是123456,只要攻击者设定一些常用弱口令的密文表,则可以通过暴力破解的方式“试试手气”
对称加密
最典型的对称加密方式就是AES,DES之类的,通信双方约定一个一样的对称加密密钥,在传输前客户端使用密钥加密好后传输给服务端,服务端通过密钥解密后拿到明文,由于密钥的不同导致即便是弱口令攻击者也根本无法做对应的暴力破解手段。看似貌似非常完美,但有个致命的问题在于这个密钥存储在哪里才安全,服务端由于都是受到防火墙并且多道密码的保护,一般很少会被人攻破,但客户端,尤其是运行在浏览器上的html,js等文件确是直接以可运行的明文代码的方式跑在用户浏览器上的,直接在客户端加密就等于把自己的加密算法和保护密钥全直接送给攻击者,因此这类的加密方式只适用于服务端与服务端之间的交互
非对称加密
非对称加密属于处理这类问题的王道,RSA算法为非对称加密的标杆性算法,通过数学方式生成“公钥”,“私钥”对,整个服务通信过程如下:
- 客户端在连接建立之初就获取到服务端的公钥
- 客户端要传输数据前使用公钥加密传输内容
- 服务端获取加密后的数据并用自己的私钥解密获取传输内容
由于公钥是公共的,所有地方都可以被拿到使用,私钥是绝密的,只能被服务端保密持有。依靠这种简单的方式就完成密钥的安全管理和通信。代码git文件夹安全传输密码SecureMethod内
实际情况
虽然看似非对称加密完美的解决通信的安全性问题,但实际的公钥私钥长度非常长,有1024位的,也有2048位的,单纯在通信时做加解密的时间在不太好的运算处理器上都高于传输时间了,因此实际投产的过程中若要对高并发的每个请求都做到这种加解密方式未免太过于难受了。因此我们引入了实际落地的方案
可以看到,最精华的落地方案就是依靠非对称加解密解决初期的对称密钥生成和交换的问题,保证对称密钥可以做到
- 每次连接到断开连接前的会话独立,减少被拦截破解后的损失,因为是会话级别的
- 一旦对称密钥安全交换完成后,后续对应会话的所有操作都是用对称加解密通信,提高通信两端的处理性能
深入浅出
回到如何安全的传输密码的问题,实际在我们的工作中若要理解清楚并实际实现对应的复杂的通信流程机制其实是很为难我们的业务开发同学的。但是我们伟大的先驱者已经为我们考虑了这种情况,于是“https”协议就诞生了,其是完全基于并兼容了http的协议,并在其之后加入了s(security)的属性,其本质就是基于我们以上讲到的原理和技术,因此若要确保你的应用可以安全的传输密码,最好的选择即是使用https协议
···································
欢迎关注课程:
《Java电商秒杀系统深度优化 从容应对亿级流量挑战》
热门评论
能不能具体举例子说明 理论的我也知道
用公钥进行对称密钥交换后用对称密钥通信。
能不能写一个例子展示一下