在日常开发中,我们常常会把一些敏感信息写进*.properties配置文件中,比如数据库密码、redis密码、admin用户的密码甚至系统用户的密码等。
我在某银行做运维时,经常会遇到这样的情况:
银行的系统都是通过堡垒机管理的,应用管理人员理论上不应该知道任何系统用户的密码,只需通过堡垒机,使用只读key或可写key即可登录相应的用户。但在一次偶尔查看应用的配置文件时,我发现应用在调用CD时需要登录系统用户,而用户名和密码均使用明文写在了配置文件中。知道了用户名密码,就可以使用su命令随意切换用户了。诸如此类的还有数据库密码等,均可在配置文件中找到,这在信息安全和权限控制等方面有很大的隐患。
所以出于安全考虑,对配置文件中敏感信息的加密就很有必要了。
不多说了,直接上方法:
- 重写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
ctxPropertiesMap; private List decryptProperties; @Override protected void loadProperties(Properties props) throws IOException { super.loadProperties(props); ctxPropertiesMap = new HashMap (); 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 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
true
converts to lowercase, *false
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. ** The conversion from hexadecimal characters to the returned bytes is * performed with the charset named by {@link #getCharsetName()}. *
* * @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. ** The conversion from hexadecimal characters to bytes to be encoded to * performed with the charset named by {@link #getCharsetName()}. *
* * @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 { /** * 密钥算法
* Java 6 只支持56bit密钥
* 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); } /** * 生成密钥
* Java 6 只支持56bit密钥
* Bouncy Castle 支持64bit密钥
* * @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; } }
- 加密敏感信息:
执行PropertiesUtil类中的main方法:
此处加密数据库密码,假设数据库密码为ROOTpublic static void main(String[] args) {//ROOT为要加密的明文 String encrypt = SecurityUtil.encryptDes("ROOT", KEY); System.out.println(encrypt); System.out.println(SecurityUtil.decryptDes(encrypt, KEY)); }
- 配置文件中该明文为密文:
db.writer.username=root db.writer.password=9u7x63ZJmcy=
- 在spring配置文件中引入配置:
classpath:config/jdbc.properties db.writer.password
搞定!