在HTML password 标签随笔这篇文章中提到了password标签在使用中需要使用JS对password进行加密后才能在网络中进行传输。
下面就介绍JavaScript数据加密插件jCryption。
使用jCryption进行表单提交加密
网上找了好久的资料,最推荐使用的是jQuery插件jCryption。同时在浩哥的博客中也有介绍。
原理如下图
客户端先生成密钥串,然后请求服务端根据客户端传入密钥串生成秘钥对。私钥保存在服务端,公钥发送至客户端。这样就实现了非对称加密(RSA)。
具体从前后台交互的http请求中可以看到
第一次http请求
第二次http请求
第三次http请求(表单提交)
具体的流程是
1.前台请求公钥(第一次、第二次HTTP请求)
http://localhost:8080/encrypt/generateKeyPair
|
|
http://localhost:8080/encrypt/handshake
|
|
- 将加密的表单提交后台(表单提交)
http://localhost:8080/encrypt/decryptData
password为前台公钥。hashObj.getHash将发起请求公钥http请求123//init service public keyvar hashObj = new jsSHA("[[${factor}]]", "ASCII");var password = hashObj.getHash("SHA-512", "HEX");
将$(“#password”).val()内数据使用password(公钥)进行加密,并提交后台
3.服务端解密password
具体的实现demo在GitHub上,地址是https://github.com/wenyaoxnxy/springboot-password-demo
项目使用Spring Boot构建,为什么使用Spring Boot呢?主要是构建项目快速,简单。
同时项目依赖redis,服务端密钥缓存在redis中,如果项目只是作为demo,可以使用全局Map缓存key值。
项目使用maven构建,使用jdk1.8。
工程构建完成后运行根目录下PasswordDemoApplication.java的main方法。项目将使用spring boot内置的tomcat运行。
在浏览器中输入http://localhost:8080/passwordEncrypt
可以测试加密解密是否成功。后台有如下判断
|
|
用户名为admin,密码为123则登录成功。
具体在生产中,可以使用如下的方式进行密码的处理
1、服务端获取明文password+salt 进行哈希算法(MD5等)入库。
2、每次登录后使用同样的“盐”进行处理,如果hash一致,则密码匹配
需要注意的是
1、一定不要使用对称密钥将密码入库
2、需要注意的是salt不能是容易破解的,尽可能的无规则,同时也要做好保密,防止外泄!
3、生产环境的salt不要在开发代码中存在。
4、如果有条件可以把密码单独部署一台加密机,与业务解耦。
后续应该讲解一下加密解密和加签验签的区别
简单来讲,加密解密,是原文的翻译和还原。
签名验签,是原文的哈希,是一种验证。
两者区别还是挺大的。后续后写一篇文章来介绍两者的具体实现和使用场景。