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;
        }
    }
}

posted @ 2022-03-15 10:22  BrandonFu  阅读(220)  评论(0)    收藏  举报