赞
踩
在MySQL数据库中, 我们常常需要对密码, ⾝份证号, ⼿机号等敏感信息进⾏加密, 以保证数据的安全性。如果使⽤明⽂存储, 当⿊客⼊侵了数据库时, 就可以轻松获取到用户的相关信息, 从⽽对用户或者企业造成信息泄漏或者财产损失。
⽬前我们用户的密码还是明⽂设置的, 为了保护用户的密码信息, 我们需要对密码进⾏加密。
密码算法主要分为三类: 对称密码算法, ⾮对称密码算法, 摘要算法
博客系统中, 我们采⽤MD5算法来进⾏加密。
摘要算法:同样的明文经过同样的摘要算法,得到的结果是一样的。
验证方法:验证经过摘要算法处理之后的结果,如果密文一样,那么就认为明文是一样的。
(1)数据库存储的一定是密文
(2)用户输入的一定是明文
(3)把用户输入的明文,经过MD5处理之后,和数据库的密文进行比对,结果一样,就认为正确
虽然经过MD5加密后的密⽂⽆法解密, 但由于相同的字符串经过MD5加密之后的密文是相同的, 当存储用户密码的数据库泄露后, 攻击者会很容易便能找到相同密码的用户, 从⽽降低了破解密码的难度。因此, 在对用户密码进⾏加密时,需要考虑对密码进⾏包装, 即使是相同的密码, 也保存为不同的密文。即使用户输⼊的是弱密码, 也考虑进⾏增强, 从⽽增加密码被攻破的难度。
采⽤为⼀个密码拼接⼀个随机字符来进⾏加密, 这个随机字符我们称之为"盐"。假如有⼀个加盐后的加密串,⿊客通过⼀定手段破解这个加密串, 他拿到的明⽂并不是我们加密前的字符串, ⽽是加密前的字符串和盐组合的字符串, 这样相对来说⼜增加了字符串的安全性。
明文+随机盐值=复杂的明文----->进行MD5加密------>密文
加密逻辑:明文+随机盐值,进行MD5加密,得到密文
数据库中存储的是:加密之后的密文,随机盐值
验证逻辑:待验证的明文+这个随机盐值,进行MD5加密,和数据库的密文进行对比
用户注册:
用户登录(校验)
public class SecurityUtilsTest { // 加密 @Test public void encrypt() { String password = "123456";// 明文 String md5Str = DigestUtils.md5DigestAsHex(password.getBytes());// 对明文进行MD5加密 System.out.println(md5Str); String salt = UUID.randomUUID().toString().replace("-", "");// 生成随机盐值 System.out.println(salt); // (salt+明文)-->MD5加密,得到密文 String securityPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes());// 密文 // 数据库存储的是:salt+密文 String finalPassword = salt+securityPassword; System.out.println(finalPassword); } }
运行程序,观察结果:
再次运行程序,会发现:相同的明文,经过加密之后,每次的密文都不相同:
@Test public void verify() { String inputPassword = "123456";// 用户输入的明文 // 数据库存储的信息:salt + MD5(salt+明文) String sqlPassword = "a0bda3270f254be0af20a86787f1ae6e4c791fde602e8207e08fd3f38df178cf"; if (sqlPassword == null || sqlPassword.length() != 64) { System.out.println("校验失败"); } String salt = sqlPassword.substring(0,32);// 拿盐值:数据库存储的前32位 // MD5(salt+用户输入的明文) String secretPassword = DigestUtils.md5DigestAsHex((salt+inputPassword).getBytes()); String finalPassword = salt+secretPassword;//最终的密文 if (finalPassword.equals(sqlPassword)) { System.out.println("校验成功"); } else { System.out.println("校验失败"); } }
运行程序,验证结果:
重新生成一个密文,继续校验:
运行结果:
@Slf4j public class SecurityUtils { // 加密 public static String encrypt(String password) { String salt = UUID.randomUUID().toString().replace("-", "");// 盐值 String securityPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes());// 密文 String finalPassword = salt + securityPassword;// 存储在数据库中:salt + MD5(salt+明文) return finalPassword; } // 校验 public static boolean verify(String inputPassword, String sqlPassword) { if (sqlPassword == null || sqlPassword.length() != 64) { log.error("数据库中的密码格式不对"); return false; } String salt = sqlPassword.substring(0,32); String secretPassword = DigestUtils.md5DigestAsHex((salt+inputPassword).getBytes()); String finalPassword = salt + secretPassword; // if (finalPassword.equals(sqlPassword)) { // return true; // } // log.error("校验失败"); // return false; return finalPassword.equals(sqlPassword); } }
数据库中的原始密码:
⽤测试类给密码123456⽣成密⽂:
846cc0edb8ea43c09f4fe8c1eef45b567c27e95c15f112417f0b27d098d14db7
7b5bd4825a5e461eb7be1128ff7033ff2c1ac41cec671b4a6bd3e2739b45ebed
修改数据库明⽂密码为密⽂, 执行SQL
update user set
password='846cc0edb8ea43c09f4fe8c1eef45b567c27e95c15f112417f0b27d098d14db7'
where id=1;
update user set
password='7b5bd4825a5e461eb7be1128ff7033ff2c1ac41cec671b4a6bd3e2739b45ebed'
where id=2;
修改UserController中登录接口密码校验的逻辑:
启动程序,访问http://127.0.0.1:8080/blog_login.html,进行登录验证:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。