在实际的开发中,我们的数据库密码一般都是明文的方式存储在数据库中,但是,这种操作非常不安全,容易被黑!
那么,此时我们就需要对其进行加密处理,市面上比较常见的就是MD5加密了,但是,普通的使用MD5来进行加密,虽然也是可以,但是架不住某些用户的密码是123456/1234/123/1234567890……等的简单密码,使用MD5加密后,虽然变得复杂了一些,但是对于MD5加密,有些实力强的黑客,能够将常见的简单的加密后的密码放到一张文档中,一一进行测试……这种虽然很费劲,但是在收益较大的情况下,黑客一定会乐于尝试的!
那么,有没有其他办法来解决这个问题呢?
那么,此时就需要用到加盐来处理了!
所谓的盐就是一个可变的字符串!用UUID来随机生成的字符串(定长)!在我们保存密码的时候,将UUID+加密后的密码一块存储到数据库中,这样当用户登录后,通过用户名拿到密码,得到盐值,用盐值跟用户输入的密码进行加密处理,然后在跟数据库中的密码进行对比…………,从而实现数据库密码实现加盐加密处理!
上面便是简单的介绍,那么,接下来……详细的说明一下吧!
加密介绍
在MySQL数据库中, 我们常常需要对密码, ⾝份证号, ⼿机号等敏感信息进⾏加密, 以保证数据的安全性. 如果使⽤明⽂存储, 当⿊客⼊侵了数据库时, 就可以轻松获取到⽤⼾的相关信息, 从⽽对⽤⼾或者企业造 成信息泄漏或者财产损失. ⽬前我们⽤⼾的密码还是明⽂设置的, 为了保护⽤⼾的密码信息, 我们需要对密码进⾏加密
密码算法分类
密码算法主要分为三类: 对称密码算法, ⾮对称密码算法, 摘要算法
- 对称密码算法 是指加密秘钥和解密秘钥相同的密码算法. 常⻅的对称密码算法有: AES, DES, 3DES, RC4, RC5, RC6 等.
- ⾮对称密码算法 是指加密秘钥和解密秘钥不同的密码算法. 该算法使⽤⼀个秘钥进⾏加密, ⽤另外⼀ 个秘钥进⾏解密. ◦ 加密秘钥可以公开,⼜称为 公钥 ◦ 解密秘钥必须保密,⼜称为 私钥 常⻅的⾮对称密码算法有: RSA, DSA, ECDSA, ECC 等
- 摘要算法 是指把任意⻓度的输⼊消息数据转化为固定⻓度的输出数据的⼀种密码算法. 摘要算法是 不可逆的, 也就是⽆法解密. 通常⽤来检验数据的完整性的重要技术, 即对数据进⾏哈希计算然后⽐ 较摘要值, 判断是否⼀致. 常⻅的摘要算法有: MD5, SHA系列(SHA1, SHA2等), CRC(CRC8, CRC16, CRC32)
加密思路
在常见的项目中, 我们大多数都是采⽤MD5算法来进⾏加密.
问题:
虽然经过MD5加密后的密⽂⽆法解密, 但由于相同的密码经过MD5哈希之后的密⽂是相同的, 当存 储⽤⼾密码的数据库泄露后, 攻击者会很容易便能找到相同密码的⽤⼾, 从⽽降低了破解密码的难度. 因 此, 在对⽤⼾密码进⾏加密时,需要考虑对密码进⾏包装, 即使是相同的密码, 也保存为不同的密⽂. 即 使⽤⼾输⼊的是弱密码, 也考虑进⾏增强, 从⽽增加密码被攻破的难度.
解决⽅案:
采⽤为⼀个密码拼接⼀个随机字符来进⾏加密, 这个随机字符我们称之为"盐". 假如有⼀个加 盐后的加密串,⿊客通过⼀定⼿段这个加密串, 他拿到的明⽂并不是我们加密前的字符串, ⽽是加密前 的字符串和盐组合的字符串, 这样相对来说⼜增加了字符串的安全性.
解密流程:
MD5是不可逆的, 通常采⽤"判断哈希值是否⼀致"来判断密码是否正确.
如果⽤⼾输⼊的密码, 和盐值⼀起拼接后的字符串经过加密算法, 得到的密⽂相同, 我们就认为密码正确 (密⽂相同, 盐值相同, 推测明⽂相同)
参考代码:
import org.springframework.util.DigestUtils;import java.util.UUID;public class SecurityUtils {public static void main(String[] args) {//加密
// String md5Str = DigestUtils.md5DigestAsHex("123456".getBytes());
// System.out.println(md5Str);//
// String uuid = UUID.randomUUID().toString();// 随机生成一个字符串, 且不会重复
// System.out.println(uuid.replace("-",""));// System.out.println(encry("123456"));
// boolean verify = verify("123456", "84f37ec4949b407bbde0373dd648c26c37843422e00a0c1b764762ae77aa3144");
// System.out.println(verify);System.out.println(encry("admin"));boolean verify = verify("admin", "bba5514860cc414aa61f826b91dabb0cbd79f8ff6bc3a89832ca659ecf070b64");System.out.println(verify);}/*** 加密* @param password 明文密码* @return 盐值+密文*/public static String encry(String password){//生成随机盐值String salt = UUID.randomUUID().toString().replace("-","");System.out.println(salt);//加密 盐值+明文String securityPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes());//数据库中存储 盐值+密文return salt+securityPassword;}/*** 校验* inputPassword用户输入的密码* sqlPassword数据库中的密码* @return*/public static boolean verify(String inputPassword, String sqlPassword){//取出盐值if (sqlPassword ==null || sqlPassword.length()!=64){return false;}String salt = sqlPassword.substring(0,32);//得到密文String securityPassword = DigestUtils.md5DigestAsHex((salt+inputPassword).getBytes());return (salt+securityPassword).equals(sqlPassword);}
}
并且修改登录验证:
修改数据库中的密码:代码已贴,自行测试!
当我们登录时,点击F12便可以看到如下效果:
此时我们的密码,便不再是明文的了!!已经是成功加盐加密处理后的密码啦!
需要注意的是,其他的有关用户密码的增改操作也得更改相应的代码!!