0%

注册场景下的密码加盐

注册场景下的密码加盐

加盐

为了防止密码明文被窃取,服务器存储加盐并加密后的密码
为了防止密码被解密,采用不可逆的md5摘要算法
$md5(md5(password)+salt)$
salt是为每个用户单独随机生成的字符串,需要在数据库中保存
前端首先用md5对密码进行加密,后端收到md5加密的密码后从数据库中取盐,和收到的密码拼接后再通过md5加密,并与数据库中存储的加密字符串比对

http环境下可以用非对称加密

用rsa算法,服务端生成公钥和私钥,公钥发送给前端,前端用公钥对密码进行加密,服务端用私钥进行解密

使用https

知乎 - 彻底搞懂HTTPS的加密原理

PasswordUtil工具类实现md5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.security.MessageDigest;
import java.util.Random;

public class PasswordUtil {

private static final char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
private static final int SALT_LENGTH = 4;

/**
* 自定义简单生成盐,是一个随机生成的长度为16的字符串,每一个字符是随机的十六进制字符
*/
public static String getSalt() {
Random random = new Random();
StringBuilder sb = new StringBuilder(SALT_LENGTH);
for (int i = 0; i < sb.capacity(); i++) {
sb.append(HEX[random.nextInt(SALT_LENGTH)]);
}
return sb.toString();
}

private static String byte2HexStr(byte[] bytes) {
StringBuilder result = new StringBuilder();
//两个字节为一个字符 2进制转16进制
for (byte byte0 : bytes) {
result.append(HEX[byte0 >>> 4 & 0xf]);
result.append(HEX[byte0 & 0xf]);
}
return result.toString();
}

public static String MD5WithSalt(String inputStr, String salt) {
try {
//申明使用MD5算法,更改参数为"SHA"就是SHA算法了
MessageDigest md = MessageDigest.getInstance("MD5");
//加盐,输入加盐
String inputWithSalt = inputStr + salt;
System.out.println("明文:" + inputStr+" 盐:"+salt);
//哈希计算,转换输出
String hashResult = byte2HexStr(md.digest(inputWithSalt.getBytes()));
System.out.println("加盐密文:" + hashResult);

return hashResult;
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
}

}