我们知道一个web应用不可避免的会有一个登陆的操作。
一般情况下有几种方式。
1、base64加密
这里暂且不谈原理,但是它是可以解密的。也就是说其实它不叫加密,就是编码而已。
2、sha1、md5和一些其他的hash算法
这里只说说md5,这种策略采取的是“不解密”。
首先md5是一种信息摘要算法,类似于java的hashcode方法,一旦加密就无法逆转。
一般开发者会这样做:把username--password 尽心md5散列计算,然后直接写入数据库(注册)。
当用户再登录时,直接验证user--password的md5散列值。有人会说:这不挺好的吗?都不用数据库搜索了,我再给md5加个索引,查找还快呢。
但是。。。。。。。你不觉得这是自欺欺人吗?
前端发送了md5,被某黑客截取到,后端不解密,那人家黑客也不解密啊。直接用这个就可以模拟用户的登录操作。
所以md5对于安全性要求不高,需求是迅速登录的web可以使用。
3、AES加密算法。
AES加密算法这里暂且不说原理。我们现在需要知道的是,它就像一个锁头一样:它的钥匙既可以开锁也可以解锁。
首先AES需要一个key,我们需要依靠这个key来加密、解密。
那么又一次回到刚才的问题———如果被黑客截获了怎么办?
那就真没办法了呢,你后台需要key解密,所以你需要传输时传送key,人家利用key和加密后的密文就可以反向解开你的密码了。
4、RSA加密算法。
这个与AES恰好相反,RSA是一个不对称加密算法。打个比方:这把锁需要两把钥匙才行。
RSA算法中存在两把钥匙publicKey和privateKey也就是常说的公匙私匙。
在用户想要通过连接进入登录界面时,后台将生成公匙和私匙,公匙通过响应对象发送给前端,前端用公匙进行加密,然后后端用私匙解密。就算公匙被截获了,黑客也无可奈何。因为破译RSA算法真的是很困难呢。
但是这里不得不提到RSA的效率问题,一套加密解密过程(虽然加密是JavaScript完成、略慢于java)需要的时间约为AES的几倍左右。经我自己试验(下篇会写上测试及其结果),AES时间是(无论首次还是多次)都在7ms以内。
RSA首次加密解密竟高达50ms以上。(240byte明文)
5、混合算法。
我们可以采取这样一个策略:
首先访问时由后端生成publicKey
然后前端生成AESkey(随机的,截获js代码也没用)、并且用AESkey对明文加密得到密文
接着把加密后的AESkey,加密后的密文传到后台
后台用privateKey解密AESkey,再用这个解密密文。
至此,同时保证了效率和安全性。
6、项目中的选择
java代码中的AES加密算法一般生成16字节(128位),24字节(192位),32字节(256位)三者选一。
RSA算法加密解密的长度一般为1024/8-11=117字节(1024也可以替换为2048、4096等这个数字越大越慢)。
密码一般为6-20个字符,其中一般都是ASCII码(大写小写数字及某些特殊字符)。
那就是20字节以内呗?所以你觉得要不要使用混合算法?
实际上我个人考虑是这样:
为了保证RSA算法效率,尽可能使用1024版本,然后使用32字节AES算法加密,这样就可以大规模对明文加密,然后混合算法。
但是。。。。你要就加密个密码吧,我觉得还真没必要。
ps:接下来几篇会阐述在java中的使用和算法基本原理。