MD5 加密设计
前端后端分别进行一次
md5+salt
加密
前端加密
为了防止密码明文在 http 上传输,则需要在前端进行一次 md5+salt 加密
- 使用
JQuery
md5
前端 JQuery md5 工具:https://github.com/emn178/js-md5
- 在前端 js 中声明一个固定盐 salt
//salt
var g_passsword_salt="ewn576ifa12";
- 登录 js 方法中加密调用
ajax
这里使用
layer
Web 组件,进行 ajax 消息弹窗
function doLogin(){var inputPass = $("#password").val();
var salt = g_passsword_salt;
// 使用盐中 5 位组合 md5 加密
var str = ""+salt.charAt(0) + salt.charAt(2) + salt.charAt(5) + inputPass + salt.charAt(7) + salt.charAt(8);
var password = md5(str);
// 使用第一次加密的密码进行 ajax 传输
$.ajax({
url: "/login/do_login",
type: "POST",
data:{mobile:$("#mobile").val(),
password: password
},
// 成功回调函数
success:function(data){layer.closeAll();
if(data.code == 2000){layer.msg("成功");
window.location.href="/goods/to_list";
}else{layer.msg(data.msg);
}
},
// 失败回调函数
error:function(){layer.closeAll();
}
});
}
后端加密存储
后端将拿到第一次 md5 加密的结果,这个密码就是表单提交上来的密码,我们需要在后端编写第二道 md5 加密方式来加密表单传来的密码后再与数据库存储的两次 md5 加密的密码进行比较,相同才能登陆成功
- 第二次加密作用:因为第一次前端加密的密码有可能被窃取的,也可能解析我们的 js 看到我们前端加密方式,可以直接得到明文密码,所以我们需要第二次后端加密再存储,这样即使前端密码被拿到了后端的也不符合。
我们将后端使用同样的方式 (也可以用不同的方式) 再次加密,盐值 salt 需要相等,用于注册时,后端进行计算出与前端第一次加密匹配的密码。
- 依赖:Apache-commons-codec
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
- MD5Util 类
public class MD5Util {public static String md5(String t){return DigestUtils.md5Hex(t);
}
private static final String salt = "ewn576ifa12";
// 前端输入的密码到表单提交的密码(第一次加密) 用于校验前端传入的密码与该方法返回的密码是否相等
public static String inputPassToFormPass(String pass){String s = "" + salt.charAt(0) + salt.charAt(2) + salt.charAt(5) + pass + salt.charAt(7) + salt.charAt(8);
return md5(s);
}
// 表单提交的密码 (第一次加密的密码) 到数据库存储的密码(第二次加密)
public static String formPassToDb(String formPass,String salt){String s = "" + salt.charAt(0) + salt.charAt(2) + salt.charAt(5) + formPass + salt.charAt(7) + salt.charAt(8);
return md5(s);
}
// 前端输入的明文密码到数据库存储的密码 可用于注册
public static String inputPassToDbPass(String input,String salt){String form = inputPassToFormPass(input);
return formPassToDb(form,salt);
}
}
- 登录业务代码
public boolean login(HttpServletResponse response,String mobile, String formPass) {
// 根据手机号获取 User 用户对象
User user = UserMapper.getById(Long.parseLong(mobile));
if(user==null){throw new GlobalException(ErrorCodeEnum.MOBILE_NOT_EXIST);// 抛出自定义异常
}
String dbPass = user.getPassword();// 获取数据库的第二次加密的密码
String dbSalt = user.getSalt();// 获取后端存储的盐
String calPass = MD5Util.formPassToDb(formPass,dbSalt);// 根据前端表单传来的密码计算出第二次加密结果
if(!calPass.equals(dbPass)){// 如果不相等
log.error("{}登录密码错误",mobile);
throw new GlobalException(ErrorCodeEnum.LOGIN_FAIL);
}
return true;
}