最新消息: 关于Git&GitHub 版本控制你了解多少?
您现在的位置是:群英 > 开发技术 > 编程语言 >
秒杀系统 MD5如何加强安全性?
CSDN发表于 2020-09-09 18:07 次浏览

思考

md5真的无法解密吗?

  • MD5加密无法解密,不可逆转,是很安全的。
  • 从技术的角度讲,MD5真的很安全,因为无法解密,破解MD5的方式只有一个:撞库(我是不知道别的方式),然而,就在大数据的今天。我今天随意的生成了几个自己常用的密码的MD5密文,很恐怖,随意百度到的工具都给破解出来了。大家可以试试,大数据是真的恐怕,我记得好像谁说过大数据是未来的生产力,也理解为什么。反正非常恐怕 

  • 所以,我相信,不久的将来,随着各种加密原文的收集,我们的MD5已不再安全,就像一个post请求一样,只是你认为他不是明文。他只是阻隔了一部分什么都不知道的人群,对于黑客(甚至入门级别的黑客)来说,只要抓到了你的请求,数据暴露无疑。

数据库存放的是用户的真实密码吗?

大学老师一般都是把真实密码存放到数据库中,但那只是演示,并非企业开发是这样做的。

数据库里面存的是做了两次MD5的用户密码 与其对应的salt值

如何判断密码输入正确?

现在我们登录的时候,要去取得数据库里面对应用户的密码和salt值,然后后台接收了前端做了一次MD5的密码formPass,然后将这个formPass去和数据库里面的salt一起再做一次MD5,然后检测是否与数据库里面存的那个密码一致。

如何灵活使用MD5加强安全性?

MD5也不是绝对安全的,但是我们可以使得破解的难度指数级增长。md5是不可逆的,不能反向解密的,网上所谓的“解密”都是把“加密”结果存储到数据库再比对的只能暴力破解,即有一个字典,从字典中读取一条记录,将密码用加salt盐值做MD5来对比数据库里面的值是否相

  1. 加盐
  2. 盐的位置灵活多变,不固定,也可倒序。

思路:

先弄清楚原理再来实现代码

两次MD5:

  • 用户端:PASS=MD5(明文+固定Salt)
  • 服务端:PASS=MD5(用户输入处理+随机Salt)

代码实现步骤:

创建秒杀User的domain类

	@Getter
	@Setter
	public class MiaoshaUser {
	private Long id;
	private String nickname;
	private String pwd;
	private String salt;
	private String head;
	private Date registerDate;
	private Date lastLoginDate;
	private Integer loginCount;

新建MiaoshaUserDao

	@Mapper
	public interface MiaoshaUserDao {
	@Select("select * from miaosha_user where id=#{id}")  //这里#{id}通过后面参数来为其赋值
	public MiaoshaUser getById(@Param("id")long id);    //绑定
	
	//绑定在对象上面了----@Param("id")long id,@Param("pwd")long pwd 效果一致
	@Update("update miaosha_user set pwd=#{pwd} where id=#{id}")
	public void update(MiaoshaUser toupdateuser);	
	//public boolean update(@Param("id")long id);    //绑定	
}

新建MiaoshaUserService

	@Service
	public class MiaoshaUserService {
	public static final String COOKIE1_NAME_TOKEN="token";
	
	@Autowired
	MiaoshaUserDao miaoshaUserDao;
	@Autowired
	RedisService redisService;
	/**
	 * 根据id取得对象,先去缓存中取
	 * @param id
	 * @return
	 */
	public MiaoshaUser getById(long id) {
		//1.取缓存	---先根据id来取得缓存
		MiaoshaUser user=redisService.get(MiaoshaUserKey.getById, ""+id, MiaoshaUser.class);
		//能再缓存中拿到
		if(user!=null) {
			return user;
		}
		//2.缓存中拿不到,那么就去取数据库
		user=miaoshaUserDao.getById(id);
		//3.设置缓存
		if(user!=null) {
			redisService.set(MiaoshaUserKey.getById, ""+id, user);
		}
		return user;
	}
	}

新建LoginController

	@RequestMapping("/login")
	@Controller
	public class LoginController{
	@Autowired
	UserService userService;
	@Autowired
	RedisService redisService;
	@Autowired
	MiaoshaUserService miaoshaUserService;	
	//slf4j
	private static Logger log=(Logger) LoggerFactory.getLogger(Logger.class);	
	@RequestMapping("/to_login")
	public String toLogin() {
		return "login";// 返回页面login
	}
	@RequestMapping("/do_login") // 作为异步操作
	@ResponseBody
	public CodeMsg doLogin(LoginVo loginVo) {// 0代表成功
		// log.info(loginVo.toString());
		if (loginVo == null) {
			return CodeMsg.SERVER_ERROR;
		}
		// 验证
		String formPass = loginVo.getPassword();
		String mobile = loginVo.getMobile();
		// 验证用户
		MiaoshaUser user = miaoshaUserService.getById(Long.parseLong(mobile));
		if (user == null) {
			return CodeMsg.MOBILE_NOTEXIST;
		}
		// 验证密码
		String dbPass = user.getPwd();
		String dbSalt = user.getSalt();
		System.out.println("dbPass:" + dbPass + "   dbSalt:" + dbSalt);
		//现在我们登录的时候,要去取得数据库里面对应用户的密码和salt值,然后后台接收了前端做了一次MD5的密码formPass,然后将这个formPass去和数据库里面的salt一起再做一次MD5,然后检测是否与数据库里面存的那个密码一致。
		// 验证密码,计算二次MD5出来的pass是否与数据库一致
		String tmppass = MD5Util.formPassToDBPass(formPass, dbSalt);
		System.out.println("formPass:" + formPass);
		System.out.println("tmppass:" + tmppass);
		if (!tmppass.equals(dbPass)) {
			return CodeMsg.PASSWORD_ERROR;
		}
		return CodeMsg.SUCCESS;
	}
}

前端login.html

引入bootstrap 引入相关的js和css

核心代码: (最下面有完整的代码)

var pass=$("#password").val();
			//pass='111111';
			//固定salt
			var salt='1a2b3c4d';
			var str=""+salt.charAt(0)+salt.charAt(2)+pass+salt.charAt(5)+salt.charAt(4);
			var password=md5(str);
			//alert(salt);
			//alert(pass);
			//alert(password);
			//与后台Md5规则一致
			//var str=""+salt.charAt(0)+salt.charAt(2)+formPass+salt.charAt(5)+salt.charAt(4);
			$.ajax({
				url:"/login/do_login",
				type:"POST",
				data:{
					mobile:$("#phone").val(),
					password:password,
				},
				success:function(data){
					if(data.code==0){
						alert("success");
						//成功后跳转
						window.location.href="/goods/to_list";
					}else{
						alert(data.msg);
					}
				},
				error:function(data){
					alert("error");
					//alert(data.msg);
				}
			});



完整的前端login.html代码:

<!DOCTYPE html>
<!-- 使用thymeleaf,配置相应的 -->
<html xmlns:th="http://www.thymeleaf.org">  <!-- th!!! 命名空间使用 -->
<head>
<meta charset="UTF-8"/><!--<meta charset="UTF-8" />  thymeleaf模板引擎默认是Template modes:HTML5解析的,所以解析比较严格。  -->
	<title>登录</title>
	<!-- thymeleaf引入静态资源的方式,@加大括弧    "/" 代表static路径-->
	<!-- jquery -->
	<!-- <script type="text/javascript" th:src="@{/js/jequery.min.js}"></script> -->
	<script type="text/javascript" th:src="@{/jquery-validation/lib/jquery-1.11.1.js}"></script>
	<!-- bootstrap -->
	<!-- <link type="text/css" rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.min.css}"/> -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"/>	
	<script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script>
	<!--jquery-validator  -->
	<script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.min.js}"></script>	
	<!-- <script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.js}"></script> -->	  
	<script type="text/javascript" th:src="@{/jquery-validation/localization/messages_zh.min.js}"></script>
	<!-- layer -->
	<script type="text/javascript" th:src="@{/layer/layer.js}"></script>
	<!-- md5.js -->
	<script type="text/javascript" th:src="@{/js/md5.min.js}"></script>
</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-sm-8 offset-sm-2">
				<div class="border-bottom mb-4 mt-4 pb-2">
					
				</div>
				<div class="card">
					<div class="card-header">
						<h6 class="card-text">Simple Form</h6><!--</h3>  -->
					</div>
					<div class="card-body">
						<form id="signupForm"  method="post" class="form-horizontal" ><!-- action="" -->
							<div class="form-group row">
								<label class="col-sm-4 col-form-label" for="phone">Phone</label>
								<div class="col-sm-6">
									<input type="text" class="form-control" id="phone" name="phone" placeholder="phone" />
								</div>
							</div>
						
							
							<div class="form-group row">
								<label class="col-sm-4 col-form-label" for="username">Username</label>
								<div class="col-sm-6">
									<input type="text" class="form-control" id="username" name="username" placeholder="Username" />
								</div>
							</div>
							<div class="form-group row">
								<label class="col-sm-4 col-form-label" for="email">Email</label>
								<div class="col-sm-6">
									<input type="text" class="form-control" id="email" name="email" placeholder="Email" />
								</div>
							</div>

							<div class="form-group row">
								<label class="col-sm-4 col-form-label" for="password">Password</label>
								<div class="col-sm-6">
									<input type="password" class="form-control" id="password" name="password" placeholder="Password" />
								</div>
							</div>

							<div class="form-group row">
								<label class="col-sm-4 col-form-label" for="confirm_password">Confirm password</label>
								<div class="col-sm-6">
									<input type="password" class="form-control" id="confirm_password" name="confirm_password" placeholder="Confirm password" />
								</div>
							</div>
							<div class="form-group row">
								<div class="col-sm-6 offset-sm-4">
									<div class="form-check">
										<input type="checkbox" id="agree" name="agree" value="agree" class="form-check-input"/>
										<label class="form-check-label">Please agree to our policy</label>
									</div>
								</div>
							</div>

							<div class="form-group row">
								<div class="col-sm-9 offset-sm-4">
									<button type="submit" class="btn btn-primary" name="signup" value="Sign up">Sign up</button>
								</div>
							</div>
						</form>
					</div>
				</div>
			</div>
		</div>
	</div>
	<script type="text/javascript">
		$.validator.setDefaults( {
			submitHandler: function () {
				var pass=$("#password").val();
				//pass='111111';
				var salt='1a2b3c4d';
				var str=""+salt.charAt(0)+salt.charAt(2)+pass+salt.charAt(5)+salt.charAt(4);
				var password=md5(str);
				//alert(salt);
				//alert(pass);
				//alert(password);
				//与后台Md5规则一致
				//var str=""+salt.charAt(0)+salt.charAt(2)+formPass+salt.charAt(5)+salt.charAt(4);
				$.ajax({
					url:"/login/do_login",
					type:"POST",
					data:{
						mobile:$("#phone").val(),
						password:password,
					},
					success:function(data){
						if(data.code==0){
							alert("success");
							//成功后跳转
							window.location.href="/goods/to_list";
						}else{
							alert(data.msg);
						}
					},
					error:function(data){
						alert("error");
						//alert(data.msg);
					}
				});
				//alert( "submitted!" );
			}
		} );
		$( document ).ready( function () {
			$( "#signupForm" ).validate( {
				rules: {
					firstname: "required",
					lastname: "required",
					username: {
						required: true,
						minlength: 2
					},
					password: {
						required: true,
						minlength: 5
					},
					confirm_password: {
						required: true,
						minlength: 5,
						equalTo: "#password"
					},
					email: {
						required: true,
						email: true
					},
					agree: "required"
				},
				messages: {
					firstname: "Please enter your firstname",
					lastname: "Please enter your lastname",
					username: {
						required: "Please enter a username",
						minlength: "Your username must consist of at least 2 characters"
					},
					password: {
						required: "Please provide a password",
						minlength: "Your password must be at least 5 characters long"
					},
					confirm_password: {
						required: "Please provide a password",
						minlength: "Your password must be at least 5 characters long",
						equalTo: "Please enter the same password as above"
					},
					email: "Please enter a valid email address",
					agree: "Please accept our policy"
				},
				errorElement: "em",
				errorPlacement: function ( error, element ) {
					// Add the `invalid-feedback` class to the error element
					error.addClass( "invalid-feedback" );

					if ( element.prop( "type" ) === "checkbox" ) {
						error.insertAfter( element.next( "label" ) );
					} else {
						error.insertAfter( element );
					}
				},
				highlight: function ( element, errorClass, validClass ) {
					$( element ).addClass( "is-invalid" ).removeClass( "is-valid" );
				},
				unhighlight: function (element, errorClass, validClass) {
					$( element ).addClass( "is-valid" ).removeClass( "is-invalid" );
				}
			} );

		} );
	</script>
</body>
</html>
标签:MD5加密
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
相关信息推荐