Properties的value值加密

现有需求,需要对配置文件里,敏感的字段进行加密,参考了properties文件加密的方法。使用时发现好处是,每次加密得到的密文都不一样,这样同样的value可以加密成不同的密码。为了支持在properties文件中,同时能读取明文的配置值和密文的配置值,采用了扩展Properties类的方法

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.Properties;
import java.util.Scanner;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class EncryptProperties extends Properties {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static SecretKeySpec secKey;
	private static final String HEADER = "ENC_";
	
	static {
		final String password = "sasflc";
		final int iterationCount = 40000;
    	final int keyLength = 128;
    	final byte[] salt = new String("fafszxcvxv1fadscxv").getBytes();
    	try {
    		secKey = createSecretKey(password.toCharArray(),
                salt, iterationCount, keyLength);
    	}
    	catch(Exception e) {
    		e.printStackTrace();
    	}
    	
	}

	@Override
	public String getProperty(String key) {
		String res = super.getProperty(key);
		return EncryptProperties.getDecryptValue(res);
	}
	
	public static String getEncryptValue(String value) {
		if(value != null) {
			try {
				value = HEADER + encrypt(value);
			}
			catch(Exception e) {
				e.printStackTrace();
			}
		}
		return value;
	}
	
	public static String getDecryptValue(String value) {
		if(value != null && value.startsWith(HEADER)) {
			try {
				String enc = value.substring(4);
				try {
					value = decrypt(enc);
				}
				catch(Exception e) {
					e.printStackTrace();
				}
			}
			catch(Exception e) {
				e.printStackTrace();
			}
		}
		return value;
	}
	
	
    private static SecretKeySpec createSecretKey(char[] password, byte[] salt, int iterationCount, int keyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
        PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterationCount, keyLength);
        SecretKey keyTmp = keyFactory.generateSecret(keySpec);
        return new SecretKeySpec(keyTmp.getEncoded(), "AES");
    }

    private static String encrypt(String property) throws GeneralSecurityException, UnsupportedEncodingException {
        Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        pbeCipher.init(Cipher.ENCRYPT_MODE, secKey);
        AlgorithmParameters parameters = pbeCipher.getParameters();
        IvParameterSpec ivParameterSpec = parameters.getParameterSpec(IvParameterSpec.class);
        byte[] cryptoText = pbeCipher.doFinal(property.getBytes("UTF-8"));
        byte[] iv = ivParameterSpec.getIV();
        return base64Encode(iv) + ":" + base64Encode(cryptoText);
    }

    private static String base64Encode(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    private static String decrypt(String string) throws GeneralSecurityException, IOException {
        String iv = string.split(":")[0];
        String property = string.split(":")[1];
        Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        pbeCipher.init(Cipher.DECRYPT_MODE, secKey, new IvParameterSpec(base64Decode(iv)));
        return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
    }

    private static byte[] base64Decode(String property) throws IOException {
        return Base64.getDecoder().decode(property);
    }

在配置文件里,所有值以ENC_开头的,按照加密值进行读取和解密;其它的值仍然采用getProperty()的方法获取明文的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值