一种简单的登录加密方案
2016-04-20 20:27
323 查看
该方案使用RSA加密和解密。
每次登录前,客户端从服务器端获取公钥和随机值。
公钥用于加密明文;
随机值可以加强每一次操作的安全性,随机值也加入明文中一并加密,服务端对随机值进行校验,校验后从缓存中销毁,这样就算被别人拿到加密后的密文再次发起请求,由于随机值已失效,请求也是无效的。
下面以js客户端为例,演示一下流程:
1、假设客户的密码以SHA256加密后存在数据库中
2.、客户输入用户名和密码点击 “登录”后,客户端发起请求,从服务器端获取公钥和随机值。
3、客户端将用户输入的密码使用SHA256加密
控制台打印出来的结果:
然后将加密后的密文传到服务器端即可。
4、服务器端代码
RSAUtils.java
View Code
maven依赖的一些jar
每次登录前,客户端从服务器端获取公钥和随机值。
公钥用于加密明文;
随机值可以加强每一次操作的安全性,随机值也加入明文中一并加密,服务端对随机值进行校验,校验后从缓存中销毁,这样就算被别人拿到加密后的密文再次发起请求,由于随机值已失效,请求也是无效的。
下面以js客户端为例,演示一下流程:
1、假设客户的密码以SHA256加密后存在数据库中
2.、客户输入用户名和密码点击 “登录”后,客户端发起请求,从服务器端获取公钥和随机值。
{ "rand": "SAXpJg", "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCK+oqElHP94+1BhhiTKX0pzziepN+C5Ff/qgmind2XvD35eWlCqzypGIXBoki526ZbsqrssbxTy5imhthe4eUTenLGUKkUgYUmDWrus8NmJm6IlXuqbGHaEY1zocsnlqVezOMj0AIUq5L65Y6e5XnEf1ludSzTF73MtFTjW8TRyQIDAQAB" }
3、客户端将用户输入的密码使用SHA256加密
<!--下载地址:https://github.com/Caligatio/jsSHA --> <script type="text/javascript" src="sha.js"></script> <!--下载地址:https://github.com/travist/jsencrypt--> <script type="text/javascript" src="jsencrypt.js"></script> <script> //用户输入的密码 var password1 = '123456'; //从服务端获得的公钥 var publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCK+oqElHP94+1BhhiTKX0pzziepN+C5Ff/qgmind2XvD35eWlCqzypGIXBoki526ZbsqrssbxTy5imhthe4eUTenLGUKkUgYUmDWrus8NmJm6IlXuqbGHaEY1zocsnlqVezOMj0AIUq5L65Y6e5XnEf1ludSzTF73MtFTjW8TRyQIDAQAB"; //从服务端获得的随机值 var rand = 'SAXpJg'; //SHA-256加密 var shaObj = new jsSHA("SHA-256", "TEXT"); shaObj.update(password1); var hash = shaObj.getHash("HEX"); //组装明文:由加密后的密码和随机值组成 var text = hash + '|' + rand; console.log("待加密的文本: " + text); //使用RSA公钥加密 var encrypt = new JSEncrypt(); encrypt.setPublicKey(publicKey); // password就可以发送到服务端进行解密校验了 var password = encrypt.encrypt(text); console.log("加密后的密文:" + password); </script>
控制台打印出来的结果:
待加密的明文:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92|SAXpJg 加密后的密文:dgUBkZPZgL76+zMbKckAxb3C072I8b4nqAZlWUD/24Hp7UpAgiKx4P90xgs1UhWM2qputsjgpsgXLCNUg2vtO9MxpQk6zWUbyh4cxL08UcmMv3KIMO5rnbFxKEmuIbQ2G/3UZT8c+w899ERLCpDVyHrKSijdpvVoKrB6PzyjP+w=
然后将加密后的密文传到服务器端即可。
4、服务器端代码
RSAUtils.java
import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.RandomStringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.google.common.collect.Maps; import io.caimi.util.RSAUtils; @RestController public class DemoController { /** * 获取公钥和随机值 * */ @RequestMapping("/secret") public Map<String, Object> secret(HttpServletRequest request) { Map<String, Object> resultMap = Maps.newHashMap(); // 获取公钥 String publicKey = RSAUtils.getBase64PublicKey(); resultMap.put("publicKey", publicKey); // 生成随机值 String rand = RandomStringUtils.randomAlphabetic(6); resultMap.put("rand", rand); // 将生成的随机值存到session中,实际使用可以存到第三方缓存中,并设置失效时间 request.getSession().setAttribute("rand", rand); return resultMap; } /** * 校验 * */ @RequestMapping(value="/check", method=RequestMethod.POST) public String check(HttpServletRequest request) { // 取得密文 String password = request.getParameter("password"); // 解密 String plaintext = RSAUtils.decrypt(password); String[] arr = plaintext.split("\\|"); // 校验随机值 String rand = arr[1]; String randInSession = (String) request.getSession().getAttribute("rand"); //随机值失效 request.getSession().removeAttribute("rand"); if(!rand.equals(randInSession)) { return "非法的请求"; } // 校验密码 String passwd = arr[0]; // 实际中根据用户名从数据库中查询出密码 String realPasswd = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"; if(!realPasswd.equals(passwd)) { return "密码输入错误"; } return "校验通过"; } }
View Code
maven依赖的一些jar
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.54</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency>
相关文章推荐
- 进程间通信-信号量详解及编程实例
- java--web.xml中url-pattern的映射规则
- C++中lower_bound函数和upper_bound函数 以及 sort(参数)
- hdu 4638 Group(莫队算法)
- UVa1592_数据库
- 【NOIP2015模拟11.3】备用钥匙
- Ubuntu init启动流程分析
- 第一次冲刺阶段(三)
- HDU 1166 敌兵布阵
- 站立会议02(第一期)
- Android studio的genymotion的安装
- 卿学姐与公主(线段树区间求最大值)
- 112. Path Sum
- 最小生成树之Prim算法---POJ1258---Agri-Net
- 加域的时候遇到的一点问题
- Linux常用快捷键
- CodeForce 652D Nested Segments 树状数组
- redis安装
- N皇后问题--回溯法
- vim中多行注释和多行删除