在日常开发中,我们常常会把一些敏感信息写进*.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<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; } }
- 加密敏感信息:
执行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 - 配置文件中该明文为密文:
db.writer.username=root db.writer.password=9u7x63ZJmcy=
- 在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>
搞定!
相关推荐
为了保护这些敏感信息不被非法访问或篡改,我们可以对Spring配置文件进行加密处理。本文将深入探讨如何在Java环境中,利用TE网络技术实现Spring配置文件的加密。 首先,我们需要理解Spring配置文件的基本结构。...
将密钥与密文都放在配置文件里,如果配置文件泄露了,那么就可以通过密钥来实现解密,达不到保护敏感信息的目的,所以密钥不要放在配置文件中。可以将密钥配置在启动项中或者在启动项目时在命令行输入。 知识点 6: ...
在Spring Boot中,我们可以利用jasypt来加密配置文件(如application.properties或application.yml)中的敏感数据,确保即使配置文件被泄露,也无法直接获取到原始的明文信息。 首先,我们需要在项目中引入jasypt的...
在Java开发中,将连接字符串存放在配置文件中是一种常见的最佳实践,这有助于提升代码的可维护性和灵活性。连接字符串通常用于数据库连接、API调用或者其他需要网络通信的服务。本篇将详细介绍如何在Java中实现这一...
而"resource"目录可能包含了配置文件、密钥文件或其他辅助资源,这些在加密解密过程中可能被用到。 总的来说,这个实例为我们展示了如何在Java中使用DES加密算法进行数据加密和解密。在实际开发中,为了增强安全性...
4. **安全考虑**:避免在配置文件中暴露敏感信息,如数据库密码或API密钥。可以使用环境变量或加密方法来存储这些数据。 5. **版本控制**:将配置文件纳入版本控制系统,如Git,以便跟踪变化和回溯错误。 6. **...
在Java编程中,配置文件是存储应用程序特定设置和参数的重要方式。这些文件通常包含数据库连接字符串、API密钥、服务器地址等敏感信息,以便在运行时动态加载,而不是硬编码到代码中。为了方便地读取和管理这些配置...
SpringBoot项目的安全性是开发过程中不容忽视的一环,特别是对于包含敏感信息和核心业务逻辑的项目,保护源代码不被轻易反编译至关重要。本文详细讲述了两种主要的防止反编译的技术:代码混淆和字节码加密。 1. **...
总之,通过加密配置文件并存储在数据库中,可以有效增强数据的安全性,防止未经授权的访问。而设计和实现这样的系统需要综合运用加密技术、数据库管理和安全策略等多个领域的知识,确保系统的整体安全性。
总的来说,基于jvmti的Java代码加密方案是一种有效的保护措施,能够防止源码被轻易反编译,尤其适用于企业级应用和敏感项目。然而,为了提高安全性,还应结合其他安全策略,如代码混淆、权限控制等,形成多层防护。
在IDEA项目中,`pom.xml`文件是Maven项目的配置文件,它定义了项目依赖、构建目标等信息。在这个项目中,`pom.xml`可能包含了Scala编译器和其他必要的库依赖,例如Scala库、JCE库等。要构建和运行这个项目,你需要...
通过以上步骤,你的Spring Boot应用就能使用PBEWITHHMACSHA512ANDAES-128加密策略,有效保护配置文件中的密码和其他敏感信息。这个过程虽然涉及多个步骤,但能显著提高应用的安全性,防止因数据泄露带来的潜在风险。...
最后,修改配置文件,配置的密码可以删除,不用显示将创建的 DBPasswordCallback 类注入到 DataSource 中。 数据库密码配置加密操作是保护数据库账号密码的重要手段,通过使用 Jasypt 或 Druid 等加密库,可以有效...
同时,对于敏感数据,最好使用环境变量、密钥管理服务等方式存储,而不是直接写入代码或配置文件。 总之,"springboot工程jar包加密"是一个关于保护Java应用安全的重要主题,通过使用工具如xjar,我们可以有效地...
数据库连接池的配置中,通常会在配置文件(如XML或properties文件)中写入加密后的密码。在应用启动时,会读取这个加密后的密码,然后进行解密操作,与用户输入的明文密码进行比对。具体的解密过程取决于加密策略,...
在给定的文件列表中,我们看到`crimson.jar`和`sunjce_provider.jar`是Java加密相关的库,它们包含必要的加密算法和提供者。 以下是实现XML加密的一些关键类和接口: 1. **CipherData**: 这个类代表了加密后的数据...
3. **加密配置文件** 使用JASYPT提供的命令行工具`encrypt`,可以将明文信息加密。例如,要加密数据库连接密码`mydbpassword`,运行如下命令: ```bash echo mydbpassword | java -cp jasypt-1.9.3.jar org....
在提供的"demo"文件中,可能包含了具体的项目结构、配置文件、源代码等,这些内容可以帮助进一步理解和实现这个Java前后端通讯AES加密及解密的案例。实际操作时,需要根据文件内容进行相应的集成和调试。
Java中的加密处理是安全编程的重要组成部分,特别是在网络通信、数据存储和身份验证等场景中...总之,Bouncy Castle为Java加密提供了丰富的选择,通过合理的配置和使用,可以提升应用的安全性,满足多样化的加密需求。