使用SHA5、MD5及UUID进行密码加密

常见的加密算法,例如DES等,都是可逆运算的算法,也就是说:如果能够获取到加密过程中的所有参数,就可以根据密文逆向运算得到原文!

在用户密码加密的领域,更希望使用的是不可逆运算的算法!这样的算法常见的有SHA(Secure Hash Algorithm)系列和MD(Message Digest)系列。

严格的说,SHA系列与MD系列的算法不是加密算法,它们归属“消息摘要算法”。

消算摘要算法的特点:

  • 原文相同,摘要相同;

  • 算法不变,摘要长度固定;

  • 原文不同,摘要可能相同,但是,机率非常低!

为了避免md5加密后的密码被反查,在处理时,应该要求:

  • 原始密码需要达到一定的安全强度(大小写字母、数字、符号)

  • 加盐,盐值应该是较长的字符串

  • 反复(多重)加密

  • 使用位数更长的摘要算法

springboot带有一个DigestUtils工具类可以实现MD和SHA算法,即:

org.springframework.util.DigestUtils;

但是apache的功能更多,即:

org.apache.commons.codec.digest.DigestUtils;

添加commons-codec依赖,可以使用Apache的DigetstUtils,实现更多种摘要运算:


    commons-codec
    commons-codec

以下案例使用Apache的DigetstUtils进行:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MessageDigestTestCase {
	
	@Test
	public void commonsEncrypt() {
		String password = "123456";
		String result = DigestUtils.sha512Hex(password);
               //ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
		System.out.println("Length=" + result.length());
		System.out.println(result);
	}
	
	@Test
	public void encrypt() {
		// 盐值
		String salt = "苍老师昨天晚上跳的海草舞还是很不错的";
		
		String password = "123456";
		
		String src = salt + password + salt + password + salt;

		String md5Password = DigestUtils.md5Hex(src);
		
		System.out.println(md5Password);
	}

}

例子:

需要完成密码加密的功能,本次加密使用了随机的盐,可以使用UUID作为随机盐。

UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。

在Java中,通过java.util.UUID类即可轻松获取到随机的UUID值:

String uuid = UUID.randomUUID().toString();

UserServiceImpl中添加加密方法:

/**
 * 获取根据MD5加密的密码
 * @param srcPassword 原密码
 * @param salt 盐值
 * @return 加密后的密码
 */
private String getMd5Password(String srcPassword, String salt) {
    // 【注意】以下加密规则是自由设计的
    // ----------------------------
    // 使用盐值 + 原密码 + 盐值
    String str = salt + srcPassword + salt;
    // 循环执行10次摘要运算
    for (int i = 0; i < 10; i++) {
        str = DigestUtils.md5Hex(str);
    }
    // 返回摘要结果
    return str;
}

然后,在reg()方法中,在执行注册之前,先获取随机盐值,获取原始密码,执行加密,然后把盐值、加密后的密码封装回User对象中,再执行注册:

// 是:用户名不存在,允许注册,则处理密码加密
// 加密-1:获取随机的UUID作为盐值
String salt = UUID.randomUUID().toString();
// 加密-2:获取用户提交的原始密码
String srcPassword = user.getPassword();
// 加密-3:基于原始密码和盐值执行加密,获取通过MD5加密的密码
String md5Password = getMd5Password(srcPassword, salt);
// 加密-4:将加密后的密码封装在user对象中
user.setPassword(md5Password);
// 加密-5:将盐值封装在user对象中
user.setSalt(salt);
// 执行注册
addnew(user);

 

 

你可能感兴趣的:(Java)