JavaWeb RSA密码加密登录
思路:每次登录前,向后端发送请求,由RSA生成一对公钥和私钥,用redis或者数据库保存用户名对应的私钥,获取公钥中的modulus和publicExponent,分别调用String#toString(int)方法,然后传到前端,前端使用security.js加密密码,然后进行登录,在后端使用私钥解密,再验证密码的正确性。
注意:
- 每次登录都需要获取公钥和私钥
- 保证每次登录时,生成的公钥和私钥与用户名是对应的。
- 1.在maven项目的pom.xml中添加下面的依赖,为了引入import org.bouncycastle.jce.provider.BouncyCastleProvider;作为安全服务提供者
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
- 2.RSAUtils工具类
RSAUtils源码:https://pan.baidu.com/s/1mkd2WWg - 3.Controller接口,为了验证加密和解密的操作是否可行。(此接口要绕过拦截器)
/**
*
* @Title: generateRSAKey
* @Description: 生成公钥和私钥
* @param username
* @return
* @date 2018年2月5日 下午4:25:05
* @author p7
*/
@GetMapping(value = "/rsaKey/{username}")
public ResultBean generateRSAKey(@PathVariable String username) {
try {
// 获取公钥和私钥
HashMap<String, Object> keys = RSAUtils.getKeys();
RSAPublicKey publicKey = (RSAPublicKey) keys.get("public");
RSAPrivateKey privateKey = (RSAPrivateKey) keys.get("private");
// 保存私钥到 redis,也可以保存到数据库
boolean res = redisService.set(username, privateKey);
if (!res) {
throw new BusinessLogicException("redis 保存失败");
}
// 将公钥传到前端
Map<String,String> map = new HashMap<String,String>();
// 注意返回modulus和exponent以16为基数的BigInteger的字符串表示形式
map.put("modulus", publicKey.getModulus().toString(16));
map.put("exponent", publicKey.getPublicExponent().toString(16));
return new ResultBean(map);
} catch (NoSuchAlgorithmException e) {
return new ResultBean(ResultBean.ERROR, e.getMessage());
} catch (BusinessLogicException e) {
return new ResultBean(ResultBean.ERROR, e.getMessage());
}
}
/**
*
* @Title: checkRSAKey
* @Description: 验证密码
* @param username
* @param password
* @return
* @date 2018年2月5日 下午4:25:43
* @author p7
*/
@GetMapping(value = "/rsaKey/{username}/{password}")
public ResultBean checkRSAKey(@PathVariable String username, @PathVariable String password) {
Object object = redisService.get(username);
try {
// 解密
String decryptByPrivateKey = RSAUtils.decryptByPrivateKey(password, (RSAPrivateKey) object);
return new ResultBean(decryptByPrivateKey);
} catch (Exception e) {
return new ResultBean(ResultBean.ERROR, "解密失败");
}
}
- 4.在登录页面引入security.js
security.js:https://pan.baidu.com/s/1nxnArBN - 5.在登录的js中对接接口。
$(document).ready(function() {
$(".loginBtn").click(function() {
var uName = $(".userName").val(); //获取用户名
var pWord = $(".passWord").val(); //获取账号
// 获取
$.ajax({
type:"get",
url:userBasePath+"rsaKey/"+uName,
success:function(data){
console.log(data);
var pwdKey = new RSAUtils.getKeyPair(data.data.exponent,"",data.data.modulus);
var reversedPwd = pWord.split("").reverse().join("");
var encrypedPwd = RSAUtils.encryptedString(pwdKey,reversedPwd);
console.log(encrypedPwd);
$.ajax({
type:"get",
url:userBasePath+"rsaKey/"+uName+"/"+encrypedPwd,
success:function(data){
console.log(data);
},
error: function(result, status, xhr) {
}
});
},
error: function(result, status, xhr) {
}
});
}
}
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: RSA加密算法
- 下一篇: RSA前端加密,java后台解密
