面试突击91:MD5 加密安全吗?( 二 )

从上述代码我们可以看出,加盐的实现具体步骤是:

  1. 使用 UUID 产生一个随机盐值;
  2. 将随机盐值 + 原始密码一起 MD5,产生一个新密码(相同的原始密码,每次都会生成一个不同的新密码);
  3. 将随机盐值 + "$"+上一步生成的新密码加在一起,就是最终生成的密码 。
那么,问题来了,既然每次生成的密码都不同,那么怎么验证密码是否正确呢?要验证密码是否正确的关键是需要先获取盐值,然后再使用相同的加密方式和步骤,生成一个最终密码和和数据库中保存的加密密码进行对比,具体实现代码如下:
import org.springframework.util.DigestUtils;import org.springframework.util.StringUtils;import java.util.UUID;public class PasswordUtil {/*** 加密(加盐处理)* @param password 待加密密码(需要加密的密码)* @return 加密后的密码*/public static String encrypt(String password) {// 随机盐值 UUIDString salt = UUID.randomUUID().toString().replaceAll("-", "");// 密码=md5(随机盐值+密码)String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());return salt + "$" + finalPassword;}/*** 解密* @param password要验证的密码(未加密)* @param securePassword 数据库中的加了盐值的密码* @return 对比结果 true OR false*/public static boolean decrypt(String password, String securePassword) {boolean result = false;if (StringUtils.hasLength(password) && StringUtils.hasLength(securePassword)) {if (securePassword.length() == 65 && securePassword.contains("$")) {String[] securePasswordArr = securePassword.split("\\$");// 盐值String slat = securePasswordArr[0];String finalPassword = securePasswordArr[1];// 使用同样的加密算法和随机盐值生成最终加密的密码password = DigestUtils.md5DigestAsHex((slat + password).getBytes());if (finalPassword.equals(password)) {result = true;}}}return result;}}总结只是简单的使用 MD5 加密是不安全的,因为每个字符串都会生成固定的密文,那么我们就可以使用彩虹表将密文还原出来,所以它不是安全的 。想要解决这个问题,我们需要通过加盐的手段,每次生成一个不同的密码,就把这个问题解决了 。
是非审之于己,毁誉听之于人,得失安之于数 。
公众号:Java面试真题解析
面试合集:https://gitee.com/mydb/interview
【面试突击91:MD5 加密安全吗?】

经验总结扩展阅读