`

java项目中,如何加密配置文件中的敏感信息

阅读更多

在日常开发中,我们常常会把一些敏感信息写进*.properties配置文件中,比如数据库密码、redis密码、admin用户的密码甚至系统用户的密码等。

我在某银行做运维时,经常会遇到这样的情况:

银行的系统都是通过堡垒机管理的,应用管理人员理论上不应该知道任何系统用户的密码,只需通过堡垒机,使用只读key或可写key即可登录相应的用户。但在一次偶尔查看应用的配置文件时,我发现应用在调用CD时需要登录系统用户,而用户名和密码均使用明文写在了配置文件中。知道了用户名密码,就可以使用su命令随意切换用户了。诸如此类的还有数据库密码等,均可在配置文件中找到,这在信息安全和权限控制等方面有很大的隐患。

所以出于安全考虑,对配置文件中敏感信息的加密就很有必要了。

不多说了,直接上方法:

  1. 重写PropertyPlaceholderConfigurer 
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.MissingResourceException;
    import java.util.Properties;
    
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
    
    
    public final class PropertiesUtil extends PropertyPlaceholderConfigurer {
        private static final byte[] KEY = {9, -1, 0, 5, 39, 8, 6, 19};
        private static Map<String, String> ctxPropertiesMap;
        private List<String> decryptProperties;
    
        @Override
        protected void loadProperties(Properties props) throws IOException {
            super.loadProperties(props);
            ctxPropertiesMap = new HashMap<String, String>();
            for (Object key : props.keySet()) {
                String keyStr = key.toString();
                String value = props.getProperty(keyStr);
                if (decryptProperties != null && decryptProperties.contains(keyStr)) {
                    value = SecurityUtil.decryptDes(value, KEY);
                    props.setProperty(keyStr, value);
                }
                ctxPropertiesMap.put(keyStr, value);
            }
        }
    
        /**
         * @param decryptPropertiesMap the decryptPropertiesMap to set
         */
        public void setDecryptProperties(List<String> decryptProperties) {
            this.decryptProperties = decryptProperties;
        }
    
        /**
         * Get a value based on key , if key does not exist , null is returned
         * 
         * @param key
         * @return
         */
        public static String getString(String key) {
            try {
                return ctxPropertiesMap.get(key);
            } catch (MissingResourceException e) {
                return null;
            }
        }
    
        /**
         * 根据key获取值
         * 
         * @param key
         * @return
         */
        public static int getInt(String key) {
            return Integer.parseInt(ctxPropertiesMap.get(key));
        }
    
        /**
         * 根据key获取值
         * 
         * @param key
         * @param defaultValue
         * @return
         */
        public static int getInt(String key, int defaultValue) {
            String value = ctxPropertiesMap.get(key);
            if (StringUtils.isBlank(value)) {
                return defaultValue;
            }
            return Integer.parseInt(value);
        }
    
        /**
         * 根据key获取值
         * @param key
         * @param defaultValue
         * @return
         */
        public static boolean getBoolean(String key, boolean defaultValue) {
            String value = ctxPropertiesMap.get(key);
            if (StringUtils.isBlank(value)) {
                return defaultValue;
            }
            return new Boolean(value);
        }
    
        public static void main(String[] args) {
            String encrypt = SecurityUtil.encryptDes("ROOT", KEY);
            System.out.println(encrypt);
            System.out.println(SecurityUtil.decryptDes(encrypt, KEY));
        }
    }
    
     
    public final class SecurityUtil {
    	private SecurityUtil() {
    	}
    
    	public static final String CHARSET = "UTF-8";
    
    	/**
    	 * BASE64解码
    	 * 
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static final byte[] decryptBASE64(String key) {
    		try {
    			return new BASE64Encoder().decode(key);
    		} catch (Exception e) {
    			throw new RuntimeException("解密错误,错误信息:", e);
    		}
    	}
    
    	/**
    	 * BASE64编码
    	 * 
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static final String encryptBASE64(byte[] key) {
    		try {
    			return new BASE64Encoder().encode(key);
    		} catch (Exception e) {
    			throw new RuntimeException("加密错误,错误信息:", e);
    		}
    	}
    
    
    	/**
    	 * 数据解密,算法(DES)
    	 * 
    	 * @param cryptData
    	 *            加密数据
    	 * @return 解密后的数据
    	 */
    	public static final String decryptDes(String cryptData, byte[] key) {
    		String decryptedData = null;
    		try {
    			// 把字符串解码为字节数组,并解密
    			decryptedData = new String(DESCoder.decrypt(decryptBASE64(cryptData), key));
    		} catch (Exception e) {
    			throw new RuntimeException("解密错误,错误信息:", e);
    		}
    		return decryptedData;
    	}
    
    	/**
    	 * 数据加密,算法(DES)
    	 * 
    	 * @param data
    	 *            要进行加密的数据
    	 * @return 加密后的数据
    	 */
    	public static final String encryptDes(String data, byte[] key) {
    		String encryptedData = null;
    		try {
    			// 加密,并把字节数组编码成字符串
    			encryptedData = encryptBASE64(DESCoder.encrypt(data.getBytes(), key));
    		} catch (Exception e) {
    			throw new RuntimeException("加密错误,错误信息:", e);
    		}
    		return encryptedData;
    	}
    
    
    }
     
    import java.io.UnsupportedEncodingException;
    
    /**
     * Hex encoder and decoder. The charset used for certain operation can be set,
     * the default is set in
     * 
     * @author ShenHuaJie
     * @version $Id: Hex.java, v 0.1 2014年3月25日 上午9:39:07 ShenHuaJie Exp $
     */
    public class Hex {
    
    	/***
    	 * Default charset name is {@link CharEncoding#UTF_8}
    	 */
    	public static final String DEFAULT_CHARSET_NAME = "UTF-8";
    
    	/***
    	 * Used to build output as Hex
    	 */
    	private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
    			'e', 'f' };
    
    	/***
    	 * Used to build output as Hex
    	 */
    	private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
    			'E', 'F' };
    
    	/***
    	 * Converts an array of characters representing hexadecimal values into an
    	 * array of bytes of those same values. The returned array will be half the
    	 * length of the passed array, as it takes two characters to represent any
    	 * given byte. An exception is thrown if the passed char array has an odd
    	 * number of elements.
    	 * 
    	 * @param data An array of characters containing hexadecimal digits
    	 * @return A byte array containing binary data decoded from the supplied
    	 *         char array.
    	 * @throws Exception Thrown if an odd number or illegal of characters is
    	 *             supplied
    	 */
    	public static byte[] decodeHex(char[] data) throws Exception {
    
    		int len = data.length;
    
    		if ((len & 0x01) != 0) {
    			throw new Exception("Odd number of characters.");
    		}
    
    		byte[] out = new byte[len >> 1];
    
    		// two characters form the hex value.
    		for (int i = 0, j = 0; j < len; i++) {
    			int f = toDigit(data[j], j) << 4;
    			j++;
    			f = f | toDigit(data[j], j);
    			j++;
    			out[i] = (byte) (f & 0xFF);
    		}
    
    		return out;
    	}
    
    	/***
    	 * Converts an array of bytes into an array of characters representing the
    	 * hexadecimal values of each byte in order. The returned array will be
    	 * double the length of the passed array, as it takes two characters to
    	 * represent any given byte.
    	 * 
    	 * @param data a byte[] to convert to Hex characters
    	 * @return A char[] containing hexadecimal characters
    	 */
    	public static char[] encodeHex(byte[] data) {
    		return encodeHex(data, true);
    	}
    
    	/***
    	 * Converts an array of bytes into an array of characters representing the
    	 * hexadecimal values of each byte in order. The returned array will be
    	 * double the length of the passed array, as it takes two characters to
    	 * represent any given byte.
    	 * 
    	 * @param data a byte[] to convert to Hex characters
    	 * @param toLowerCase <code>true</code> converts to lowercase,
    	 *            <code>false</code> to uppercase
    	 * @return A char[] containing hexadecimal characters
    	 * @since 1.4
    	 */
    	public static char[] encodeHex(byte[] data, boolean toLowerCase) {
    		return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    	}
    
    	/***
    	 * Converts an array of bytes into an array of characters representing the
    	 * hexadecimal values of each byte in order. The returned array will be
    	 * double the length of the passed array, as it takes two characters to
    	 * represent any given byte.
    	 * 
    	 * @param data a byte[] to convert to Hex characters
    	 * @param toDigits the output alphabet
    	 * @return A char[] containing hexadecimal characters
    	 * @since 1.4
    	 */
    	protected static char[] encodeHex(byte[] data, char[] toDigits) {
    		int l = data.length;
    		char[] out = new char[l << 1];
    		// two characters form the hex value.
    		for (int i = 0, j = 0; i < l; i++) {
    			out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
    			out[j++] = toDigits[0x0F & data[i]];
    		}
    		return out;
    	}
    
    	/***
    	 * Converts an array of bytes into a String representing the hexadecimal
    	 * values of each byte in order. The returned String will be double the
    	 * length of the passed array, as it takes two characters to represent any
    	 * given byte.
    	 * 
    	 * @param data a byte[] to convert to Hex characters
    	 * @return A String containing hexadecimal characters
    	 * @since 1.4
    	 */
    	public static String encodeHexString(byte[] data) {
    		return new String(encodeHex(data));
    	}
    
    	/***
    	 * Converts a hexadecimal character to an integer.
    	 * 
    	 * @param ch A character to convert to an integer digit
    	 * @param index The index of the character in the source
    	 * @return An integer
    	 * @throws Exception Thrown if ch is an illegal hex character
    	 */
    	protected static int toDigit(char ch, int index) throws Exception {
    		int digit = Character.digit(ch, 16);
    		if (digit == -1) {
    			throw new Exception("Illegal hexadecimal charcter " + ch + " at index " + index);
    		}
    		return digit;
    	}
    
    	private static String charsetName = DEFAULT_CHARSET_NAME;
    
    	/***
    	 * Creates a new codec with the default charset name
    	 * {@link #DEFAULT_CHARSET_NAME}
    	 */
    	public Hex() {
    	}
    
    	/***
    	 * Creates a new codec with the given charset name.
    	 * 
    	 * @param csName the charset name.
    	 * @since 1.4
    	 */
    	public Hex(String csName) {
    		charsetName = csName;
    	}
    
    	/***
    	 * Converts an array of character bytes representing hexadecimal values into
    	 * an array of bytes of those same values. The returned array will be half
    	 * the length of the passed array, as it takes two characters to represent
    	 * any given byte. An exception is thrown if the passed char array has an
    	 * odd number of elements.
    	 * 
    	 * @param array An array of character bytes containing hexadecimal digits
    	 * @return A byte array containing binary data decoded from the supplied
    	 *         byte array (representing characters).
    	 * @throws Exception Thrown if an odd number of characters is supplied to
    	 *             this function
    	 * @see #decodeHex(char[])
    	 */
    	public byte[] decode(byte[] array) throws Exception {
    		try {
    			return decodeHex(new String(array, getCharsetName()).toCharArray());
    		} catch (Exception e) {
    			throw new Exception(e.getMessage(), e);
    		}
    	}
    
    	/***
    	 * Converts a String or an array of character bytes representing hexadecimal
    	 * values into an array of bytes of those same values. The returned array
    	 * will be half the length of the passed String or array, as it takes two
    	 * characters to represent any given byte. An exception is thrown if the
    	 * passed char array has an odd number of elements.
    	 * 
    	 * @param object A String or, an array of character bytes containing
    	 *            hexadecimal digits
    	 * @return A byte array containing binary data decoded from the supplied
    	 *         byte array (representing characters).
    	 * @throws Exception Thrown if an odd number of characters is supplied to
    	 *             this function or the object is not a String or char[]
    	 * @see #decodeHex(char[])
    	 */
    	public Object decode(Object object) throws Exception {
    		try {
    			char[] charArray = object instanceof String ? ((String) object).toCharArray() : (char[]) object;
    			return decodeHex(charArray);
    		} catch (ClassCastException e) {
    			throw new Exception(e.getMessage(), e);
    		}
    	}
    
    	/***
    	 * Converts an array of bytes into an array of bytes for the characters
    	 * representing the hexadecimal values of each byte in order. The returned
    	 * array will be double the length of the passed array, as it takes two
    	 * characters to represent any given byte.
    	 * <p>
    	 * The conversion from hexadecimal characters to the returned bytes is
    	 * performed with the charset named by {@link #getCharsetName()}.
    	 * </p>
    	 * 
    	 * @param array a byte[] to convert to Hex characters
    	 * @return A byte[] containing the bytes of the hexadecimal characters
    	 * @throws IllegalStateException if the charsetName is invalid. This API
    	 *             throws {@link IllegalStateException} instead of
    	 *             {@link Exception} for backward compatibility.
    	 * @see #encodeHex(byte[])
    	 */
    	public static byte[] encode(byte[] array) throws UnsupportedEncodingException {
    		String string = encodeHexString(array);
    		if (string == null) {
    			return null;
    		}
    		return string.getBytes(charsetName);
    	}
    
    	/***
    	 * Converts a String or an array of bytes into an array of characters
    	 * representing the hexadecimal values of each byte in order. The returned
    	 * array will be double the length of the passed String or array, as it
    	 * takes two characters to represent any given byte.
    	 * <p>
    	 * The conversion from hexadecimal characters to bytes to be encoded to
    	 * performed with the charset named by {@link #getCharsetName()}.
    	 * </p>
    	 * 
    	 * @param object a String, or byte[] to convert to Hex characters
    	 * @return A char[] containing hexadecimal characters
    	 * @throws Exception Thrown if the given object is not a String or byte[]
    	 * @see #encodeHex(byte[])
    	 */
    	public Object encode(Object object) throws Exception {
    		try {
    			byte[] byteArray = object instanceof String ? ((String) object).getBytes(getCharsetName())
    					: (byte[]) object;
    			return encodeHex(byteArray);
    		} catch (ClassCastException e) {
    			throw new Exception(e.getMessage(), e);
    		} catch (Exception e) {
    			throw new Exception(e.getMessage(), e);
    		}
    	}
    
    	/***
    	 * Gets the charset name.
    	 * 
    	 * @return the charset name.
    	 * @since 1.4
    	 */
    	public String getCharsetName() {
    		return charsetName;
    	}
    
    	/***
    	 * Returns a string representation of the object, which includes the charset
    	 * name.
    	 * 
    	 * @return a string representation of the object.
    	 */
    	@Override
    	public String toString() {
    		return super.toString() + "[charsetName=" + charsetName + "]";
    	}
    }
    
     
    import java.security.MessageDigest;
    
    /**
     * MD加密组件
     * 
     * @author du
     * @version 1.0
     * @since 1.0
     */
    public abstract class MDCoder {
    
    	/**
    	 * MD2加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static byte[] encodeMD2(byte[] data) throws Exception {
    		// 初始化MessageDigest
    		MessageDigest md = MessageDigest.getInstance("MD2");
    		// 执行消息摘要
    		return md.digest(data);
    	}
    
    	/**
    	 * MD4加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static byte[] encodeMD4(byte[] data) throws Exception {
    		// 初始化MessageDigest
    		MessageDigest md = MessageDigest.getInstance("MD4");
    		// 执行消息摘要
    		return md.digest(data);
    	}
    
    	/**
    	 * MD5加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static byte[] encodeMD5(byte[] data) throws Exception {
    		// 初始化MessageDigest
    		MessageDigest md = MessageDigest.getInstance("MD5");
    		// 执行消息摘要
    		return md.digest(data);
    	}
    
    	/**
    	 * Tiger加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static byte[] encodeTiger(byte[] data) throws Exception {
    		// 初始化MessageDigest
    		MessageDigest md = MessageDigest.getInstance("Tiger");
    		// 执行消息摘要
    		return md.digest(data);
    	}
    
    	/**
    	 * TigerHex加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static String encodeTigerHex(byte[] data) throws Exception {
    		// 执行消息摘要
    		byte[] b = encodeTiger(data);
    		// 做十六进制编码处理
    		return new String(Hex.encode(b));
    	}
    
    	/**
    	 * Whirlpool加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static byte[] encodeWhirlpool(byte[] data) throws Exception {
    		// 初始化MessageDigest
    		MessageDigest md = MessageDigest.getInstance("Whirlpool");
    		// 执行消息摘要
    		return md.digest(data);
    	}
    
    	/**
    	 * WhirlpoolHex加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static String encodeWhirlpoolHex(byte[] data) throws Exception {
    		// 执行消息摘要
    		byte[] b = encodeWhirlpool(data);
    		// 做十六进制编码处理
    		return new String(Hex.encode(b));
    	}
    
    	/**
    	 * GOST3411加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static byte[] encodeGOST3411(byte[] data) throws Exception {
    		// 初始化MessageDigest
    		MessageDigest md = MessageDigest.getInstance("GOST3411");
    		// 执行消息摘要
    		return md.digest(data);
    	}
    
    	/**
    	 * GOST3411Hex加密
    	 * 
    	 * @param data 待加密数据
    	 * @return byte[] 消息摘要
    	 * @throws Exception
    	 */
    	public static String encodeGOST3411Hex(byte[] data) throws Exception {
    		// 执行消息摘要
    		byte[] b = encodeGOST3411(data);
    		// 做十六进制编码处理
    		return new String(Hex.encode(b));
    	}
    }
    
     
    import java.security.InvalidKeyException;
    import java.security.Key;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.spec.InvalidKeySpecException;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.KeyGenerator;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    
    /**
     * DES安全编码组件
     * 
     * @author du
     * @version 1.0
     * @since 1.0
     */
    public abstract class DESCoder {
    
    	/**
    	 * 密钥算法 <br>
    	 * Java 6 只支持56bit密钥 <br>
    	 * Bouncy Castle 支持64bit密钥
    	 */
    	public static final String KEY_ALGORITHM = "DES";
    
    	/**
    	 * 加密/解密算法 / 工作模式 / 填充方式
    	 */
    	public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5PADDING";
    
    	/**
    	 * 转换密钥
    	 * 
    	 * @param key 二进制密钥
    	 * @return Key 密钥
    	 * @throws InvalidKeyException
    	 * @throws NoSuchAlgorithmException
    	 * @throws InvalidKeySpecException
    	 * @throws Exception
    	 */
    	private static Key toKey(byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
    		// 实例化DES密钥材料
    		DESKeySpec dks = new DESKeySpec(key);
    		// 实例化秘密密钥工厂
    		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
    		// 生成秘密密钥
    		SecretKey secretKey = keyFactory.generateSecret(dks);
    		return secretKey;
    	}
    
    	/**
    	 * 解密
    	 * 
    	 * @param data 待解密数据
    	 * @param key 密钥
    	 * @return byte[] 解密数据
    	 * @throws InvalidKeySpecException
    	 * @throws NoSuchAlgorithmException
    	 * @throws InvalidKeyException
    	 * @throws NoSuchPaddingException
    	 * @throws BadPaddingException
    	 * @throws IllegalBlockSizeException
    	 * @throws Exception
    	 */
    	public static byte[] decrypt(byte[] data, byte[] key) throws InvalidKeyException, NoSuchAlgorithmException,
    			InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
    		// 还原密钥
    		Key k = toKey(key);
    		// 实例化
    		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    		// 初始化,设置为解密模式
    		cipher.init(Cipher.DECRYPT_MODE, k);
    		// 执行操作
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 * 加密
    	 * 
    	 * @param data 待加密数据
    	 * @param key 密钥
    	 * @return byte[] 加密数据
    	 * @throws NoSuchPaddingException
    	 * @throws NoSuchAlgorithmException
    	 * @throws InvalidKeyException
    	 * @throws BadPaddingException
    	 * @throws IllegalBlockSizeException
    	 * @throws InvalidKeySpecException
    	 * @throws Exception
    	 */
    	public static byte[] encrypt(byte[] data, byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException,
    			InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
    		// 还原密钥
    		Key k = toKey(key);
    		// 实例化
    		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    		// 初始化,设置为加密模式
    		cipher.init(Cipher.ENCRYPT_MODE, k);
    		// 执行操作
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 * 生成密钥 <br>
    	 * Java 6 只支持56bit密钥 <br>
    	 * Bouncy Castle 支持64bit密钥 <br>
    	 * 
    	 * @return byte[] 二进制密钥
    	 * @throws NoSuchAlgorithmException
    	 * @throws Exception
    	 */
    	public static byte[] initKey() throws NoSuchAlgorithmException {
    		/*
    		 * 实例化密钥生成器
    		 * 
    		 * 若要使用64bit密钥注意替换 将下述代码中的KeyGenerator.getInstance(CIPHER_ALGORITHM);
    		 * 替换为KeyGenerator.getInstance(CIPHER_ALGORITHM, "BC");
    		 */
    		KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
    		/*
    		 * 初始化密钥生成器 若要使用64bit密钥注意替换 将下述代码kg.init(56); 替换为kg.init(64);
    		 */
    		kg.init(56, new SecureRandom());
    		// 生成秘密密钥
    		SecretKey secretKey = kg.generateKey();
    		// 获得密钥的二进制编码形式
    		return secretKey.getEncoded();
    	}
    }
    
     
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PushbackInputStream;
    
    /**
     * 密码器类
     * 
     * @author du
     * @since 2017-11-19
     */
    public class BASE64Encoder {
    
        /**
         * 译码数据源
         */
        private static final char[] PEM_ARRAY = {
            // 0  1   2   3    4    5    6    7
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', // 0
            'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', // 1
            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', // 2
            'y', 'z', '1', '2', '3', '4', '5', '6', // 3
            '7', '8', '9', '0', 'A', 'B', 'C', 'D', // 4
            'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', // 5
            'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', // 6
            'U', 'V', 'W', 'X', 'Y', 'Z', '+', '/' // 7
        };
    
        private static final byte[] pem_convert_array = new byte[256];
    
        private byte[] decode_buffer = new byte[4];
    
        public BASE64Encoder() {
        }
    
        /**
         * 编码
         */
        public String encode(byte[] bt) {
            int totalBits = bt.length * 8;
            int nn = totalBits % 6;
            int curPos = 0;// process bits
            StringBuilder toReturn = new StringBuilder(32);
            while (curPos < totalBits) {
                int bytePos = curPos / 8;
                switch (curPos % 8) {
                case 0:
                    toReturn.append(PEM_ARRAY[(bt[bytePos] & 0xfc) >> 2]);
                    break;
                case 2:
                    toReturn.append(PEM_ARRAY[(bt[bytePos] & 0x3f)]);
                    break;
                case 4:
                    if (bytePos == bt.length - 1) {
                        toReturn.append(PEM_ARRAY[((bt[bytePos] & 0x0f) << 2) & 0x3f]);
                    } else {
                        int pos = (((bt[bytePos] & 0x0f) << 2) | ((bt[bytePos + 1] & 0xc0) >> 6)) & 0x3f;
                        toReturn.append(PEM_ARRAY[pos]);
                    }
                    break;
                case 6:
                    if (bytePos == bt.length - 1) {
                        toReturn.append(PEM_ARRAY[((bt[bytePos] & 0x03) << 4) & 0x3f]);
                    } else {
                        int pos = (((bt[bytePos] & 0x03) << 4) | ((bt[bytePos + 1] & 0xf0) >> 4)) & 0x3f;
                        toReturn.append(PEM_ARRAY[pos]);
                    }
                    break;
                default:
                    break;
                }
                curPos += 6;
            }
            if (nn == 2) {
                toReturn.append("==");
            } else if (nn == 4) {
                toReturn.append("=");
            }
            return toReturn.toString();
        }
    
        /**
         * 解码
         */
        public byte[] decode(String str) throws IOException {
            byte[] arrayOfByte = str.getBytes();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(arrayOfByte);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            decodeBuffer(inputStream, outputStream);
            return outputStream.toByteArray();
        }
    
        private void decodeBuffer(InputStream paramInputStream, OutputStream paramOutputStream) throws IOException {
            PushbackInputStream localPushbackInputStream = new PushbackInputStream(paramInputStream);
            int j = 0;
            while (true) {
                try {
                    int k = bytesPerLine();
                    int i = 0;
                    if (i + bytesPerAtom() < k) {
                        decodeAtom(localPushbackInputStream, paramOutputStream, bytesPerAtom());
                        j += bytesPerAtom();
                        i += bytesPerAtom();
                        continue;
                    }
    
                    if (i + bytesPerAtom() == k) {
                        decodeAtom(localPushbackInputStream, paramOutputStream, bytesPerAtom());
                        j += bytesPerAtom();
                    } else {
                        decodeAtom(localPushbackInputStream, paramOutputStream, k - i);
                        j += k - i;
                    }
                } catch (RuntimeException e) {
                    String.valueOf(j);
                    break;
                }
            }
        }
    
        private int bytesPerAtom() {
            return 4;
        }
    
        private int bytesPerLine() {
            return 72;
        }
    
        private void decodeAtom(PushbackInputStream paramPushbackInputStream, OutputStream paramOutputStream, int paramInt)
            throws IOException {
            int i;
            int j = -1;
            int k = -1;
            int m = -1;
            int n = -1;
    
            if (paramInt < 2) {
                throw new java.lang.ArrayStoreException("BASE64Decoder: Not enough bytes for an atom.");
            }
            do {
                i = paramPushbackInputStream.read();
                if (i == -1) {
                    throw new RuntimeException();
                }
            } while ((i == 10) || (i == 13));
            this.decode_buffer[0] = (byte)i;
    
            i = readFully(paramPushbackInputStream, this.decode_buffer, 1, paramInt - 1);
            if (i == -1) {
                throw new RuntimeException();
            }
    
            if ((paramInt > 3) && (this.decode_buffer[3] == 61)) {
                paramInt = 3;
            }
            if ((paramInt > 2) && (this.decode_buffer[2] == 61)) {
                paramInt = 2;
            }
            switch (paramInt) {
            case 4:
                n = pem_convert_array[(this.decode_buffer[3] & 0xFF)];
            case 3:
                m = pem_convert_array[(this.decode_buffer[2] & 0xFF)];
            case 2:
                k = pem_convert_array[(this.decode_buffer[1] & 0xFF)];
                j = pem_convert_array[(this.decode_buffer[0] & 0xFF)];
            }
    
            switch (paramInt) {
            case 2:
                paramOutputStream.write((byte)(j << 2 & 0xFC | k >>> 4 & 0x3));
                break;
            case 3:
                paramOutputStream.write((byte)(j << 2 & 0xFC | k >>> 4 & 0x3));
                paramOutputStream.write((byte)(k << 4 & 0xF0 | m >>> 2 & 0xF));
                break;
            case 4:
                paramOutputStream.write((byte)(j << 2 & 0xFC | k >>> 4 & 0x3));
                paramOutputStream.write((byte)(k << 4 & 0xF0 | m >>> 2 & 0xF));
                paramOutputStream.write((byte)(m << 6 & 0xC0 | n & 0x3F));
            }
        }
    
        private int readFully(InputStream paramInputStream, byte[] paramArrayOfByte, int paramInt1, int paramInt2)
            throws IOException {
            for (int i = 0; i < paramInt2; i++) {
                int j = paramInputStream.read();
                if (j == -1) {
                    return i == 0 ? -1 : i;
                }
                paramArrayOfByte[(i + paramInt1)] = (byte)j;
            }
            return paramInt2;
        }
    
        static {
            for (int i = 0; i < 255; i++) {
                pem_convert_array[i] = -1;
            }
            for (int i = 0; i < PEM_ARRAY.length; i++)
                pem_convert_array[PEM_ARRAY[i]] = (byte)i;
        }
    }
    
     
  2. 加密敏感信息:

    执行PropertiesUtil类中的main方法:

        public static void main(String[] args) {//ROOT为要加密的明文
            String encrypt = SecurityUtil.encryptDes("ROOT", KEY);
            System.out.println(encrypt);
            System.out.println(SecurityUtil.decryptDes(encrypt, KEY));
        }
     此处加密数据库密码,假设数据库密码为ROOT

     

  3. 配置文件中该明文为密文:
    db.writer.username=root
    db.writer.password=9u7x63ZJmcy=
     
  4. 在spring配置文件中引入配置:
    	<!-- 引入属性文件 -->
    	<bean class="com.ds.core.util.PropertiesUtil">
    		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    		<property name="ignoreResourceNotFound" value="true" />
    		<property name="locations">
    			<list>
    				<value>classpath:config/jdbc.properties</value>
    			</list>
    		</property>
    		<property name="decryptProperties">
    			<array>
    				<!-- 需要解密的配置 -->
    				<value>db.writer.password</value>
    			</array>
    		</property>
    	</bean>
     

 搞定!酷

0
0
分享到:
评论

相关推荐

    高效数据脱敏工具 - MyBatis-Cipher,基于MyBatis的数据库敏感信息加密解密方案

    MyBatis-Cipher 是一款基于 Java 语言开发的数据库敏感信息加密解密方案,专为 MyBatis 设计。它能够在数据进出数据库(DB)的过程中自动对敏感信息进行脱敏处理,极大提高了数据安全性,同时避免了开发者手动实现...

    一个Java配置文件加密解密工具类分享

    在 JavaEE 配置文件中,例如 XML 或者 properties 文件,由于某些敏感信息不希望普通人员看见,则可以采用加密的方式存储,程序读取后进行解密

    class加密,java加密,jar加密-Web虎 1.3

    增加安装配置文件、可自行定制安装项:setup。ini 2008-8-25 改动安装界面 2008-8-18 界面美化 2008-8-3 web虎采用新驱动、实时加解密、不再用b盘来保存了 2008-4-10 自动升级精灵 2008-4-4 修正了几个bug 1. 启动后...

    jasypt API Docs 1.9 (CHM格式)

    Jasypt开发团队推出了Java加密工具Jasypt 1.4,它可与Spring Framework、Hibernate和Acegi Security集成。 Jasypt 1.4的新特征包括:加密属性文件(encryptable properties files)、Spring Framework集成、加密...

    jasypt-1.9.3.jar

    &gt;根据Jasypt官方文档,Jasypt可用于加密任务与应用程序,例如加密密码、敏感信息和数据通信、创建完整检查数据的sums. 其他性能包括高安全性、基于标准的加密技术、可同时单向和双向加密的加密密码、文本、数字和二...

    jasypt-1.9.3-dist.zip

    根据Jasypt官方文档,Jasypt可用于加密任务与应用程序,例如加密密码、敏感信息和数据通信、创建完整检查数据的sums. 其他性能包括高安全性、基于标准的加密技术、可同时单向和双向加密的加密密码、文本、数字和二...

    sec:用于Palantir加密配置的伴侣工具

    除了Palantir Configuration Values库提供的核心功能之外,此工具还提供了一个易于使用的命令行界面,该界面通过以下方式扩展了原始库: 提供基于模式对整个配置文件中的敏感信息进行加密的功能。 了解常见的配置...

    Java安全性编程实例(徐迎晓)

    # 硬盘上的文件中有敏感数据,如何防止被黑客看到? # 主要内容 # 本章解决的是数据内容的安全性,介绍Java的加密和解密技术。学完该章可以通过Java编程对各种数据进行各种形式的加密。密码学也是安全机制的基础。 ...

    jPasswordObfuscator:用于敏感数据混淆和去混淆的可扩展 Java 库和命令行实用程序

    由于数据和密钥紧密地保存在一起(软件中的密钥,配置文件中的数据),这种方法不能为确定的攻击者提供任何安全性,只是一种向临时旁观者隐藏(混淆)数据的方法。 Maven 依赖项位于: &lt;dependency&gt; &lt;groupId&gt;rs.in...

    MeyboMail Web(Java)开源简化-meybomailweb源码

    灵活的配置:通过配置文件或数据库,MeyboMail Web 允许用户或开发者轻松调整各种设置,如邮件服务器设置、用户权限等。 安全性:由于处理的是敏感数据(如邮件内容、用户凭证等),MeyboMail Web 通常注重安全性,...

    java开发手册(全套含2022年黄山版)

    配置文件中的密码需要加密等。 2)新增描述中的正反例 2 条。比如,多个构造方法次序、NoSuchMethodError 处 理;新增扩展说明 5 条。比如,父集合元素的增加或删除异常等。 3)修改描述 22 处。比如,魔法值的示例...

    基于JavaWeb实现用于网络安全传输隐私随机密码平台源码+使用教程.zip

    修改一下src下的peizhi(配置文件),然后打包成war包keyword.war 将其war包后粘贴到weapps中去,注意名称要是keyword.war,否则会报错,复制后使用tomcat中bin下的start.bat来开启tomcat,这时服务启动,注意关闭cmd...

    AnnouncementsPortlet:JSR-286 Portlet在uPortal中实施公告

    使用加密敏感值,然后将其包含在.properties文件中,如下所示: hibernate.connection.password =ENC(9ffpQXJi/EPih9o+ Xshm5g ==) 使用UP_JASYPT_KEY环境变量指定加密密钥。 依存关系 这些依赖项预计将由整体...

    javasnmp源码-switch-monitor:广东工业大学交换机监控

    java ... 由于配置文件涉及敏感数据以及系统环境不同,故使用了ulisesbocchio进行加密,进行编译时需在resources目录下自行新建一个application-encrypt.yml的文件。  内容包括 jasypt.encryptor.pas

    CalendarPortlet:JSR-168 Portlet在uPortal中实现日历查看

    使用加密敏感值,然后将其包含在.properties文件中,如下所示: hibernate.connection.password=ENC(9ffpQXJi/EPih9o+Xshm5g==)使用UP_JASYPT_KEY环境变量指定加密密钥。迁移至v2.3.0 如果使用Exchange Web ...

    asp.net知识库

    革新:.NET 2.0的自定义配置文件体系初探 关于如何在ASP.NET 2.0中定制Expression Builders 怎么在ASP.NET 2.0中使用Membership asp.net 2.0-实现数据访问(1) ASP.NET 2.0 新特性 .NET 2.0里使用强类型数据创建...

    hc-sdk-kmp:Health Client SDK(Android和JVM),用于与Data4Life Personal Health Data Platform进行交互

    这是Data4Life的Android和Java SDK.SDK封装了Data4Life个人健康数据平台(PHDP)的后端功能,并实现了对患者数据的端到端加密,它允许用户将敏感的健康数据存储在安全平台上并将其分享给授权人员和应用程序。...

    MySQL 5.1中文手冊

    5.2.4. MySQL实例管理器配置文件 5.2.5. MySQL实例管理器识别的命令 5.3. mysqld:MySQL服务器 5.3.1. mysqld命令行选项 5.3.2. SQL服务器模式 5.3.3. 服务器系统变量 5.3.4. 服务器状态变量 5.4. mysql_fix_...

Global site tag (gtag.js) - Google Analytics