Spring security password encode
Spring Security 中 authentication需要的密码进行加密。加密算法有很多。本文讲述SHA-256加密的过程
摘要基础算法:
static byte[] digest(String algorithm, byte[] value) throws NoSuchAlgorithmException {
int iterator = 1024;
// 生成消息摘要算法
MessageDigest digester = createDigest(algorithm);
// 进行1024次摘要算法
for (int i = 0; i < iterator; i++) {
value = digester.digest(value);
}
return value;
}
生成摘要算法:
static MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException {
MessageDigest instance = null;
try {
instance = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw e;
}
return instance;
}
编码算法:
/**
* 编码算法
* 将salt与rawPassword连接在一起;
* 调用摘要算法
* 将salt与生成的摘要连接在一起在生成16进制字符串
*/
static String encode(String rawPassword, byte[] salt) {
byte[] concatenate = EncodingUtils.concatenate(salt, Utf8.encode(rawPassword));
try {
byte[] digest = digest("SHA-256", concatenate);
byte[] encodedPassword = EncodingUtils.concatenate(salt, digest);
return new String(Hex.encode(encodedPassword));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
密码校验:
byte[] encodedBytes = Hex.decode(encodedPassword);
byte[] saltDecoded = EncodingUtils.subArray(encodedBytes, 0, bytesKeyGenerator.getKeyLength());
String encodedPassword2 = encode(rawPassword, saltDecoded);
System.out.println(encodedPassword.equals(encodedPassword2));
用户的密码会被持久化到数据库。从数据库中拿到的密码,可以从中获取salt。软后再对用户登陆时填写的密码进行加密,比较两个加密后的字符串是否一致。
完整的代码:
package com.brandon.gssecuringweb;
import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.crypto.codec.Utf8;
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
import org.springframework.security.crypto.keygen.KeyGenerators;
import org.springframework.security.crypto.util.EncodingUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
String rawPassword = "password";
BytesKeyGenerator bytesKeyGenerator = KeyGenerators.secureRandom();
byte[] salt = bytesKeyGenerator.generateKey();
System.out.println("Salt encode:" + Arrays.toString(salt));
String encodedPassword = encode(rawPassword, salt);
System.out.println(encodedPassword);
byte[] encodedBytes = Hex.decode(encodedPassword);
byte[] saltDecoded = EncodingUtils.subArray(encodedBytes, 0, bytesKeyGenerator.getKeyLength());
String encodedPassword2 = encode(rawPassword, saltDecoded);
System.out.println(encodedPassword.equals(encodedPassword2));
}
static MessageDigest createDigest(String algorithm) throws NoSuchAlgorithmException {
MessageDigest instance = null;
try {
instance = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw e;
}
return instance;
}
static byte[] digest(String algorithm, byte[] value) throws NoSuchAlgorithmException {
int iterator = 1024;
MessageDigest digester = createDigest(algorithm);
for (int i = 0; i < iterator; i++) {
value = digester.digest(value);
}
return value;
}
/**
* 编码算法
* 将salt与rawPassword连接在一起;
* 调用摘要算法
* 将salt与生成的摘要连接在一起在生成16进制字符串
* @param rawPassword
* @param salt
* @return
*/
static String encode(String rawPassword, byte[] salt) {
byte[] concatenate = EncodingUtils.concatenate(salt, Utf8.encode(rawPassword));
try {
byte[] digest = digest("SHA-256", concatenate);
byte[] encodedPassword = EncodingUtils.concatenate(salt, digest);
return new String(Hex.encode(encodedPassword));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
}

浙公网安备 33010602011771号