All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.gdface.utils.encrypt.EncryptedProperties Maven / Gradle / Ivy
package net.gdface.utils.encrypt;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.InvalidPropertiesFormatException;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Properties;
import static net.gdface.utils.encrypt.AES128ECBNoPadding.wrapDecrypt;
import static net.gdface.utils.encrypt.AES128ECBNoPadding.wrapEncrypt;
/**
* {@link Properties}的子类,
* 基于{@link AES128ECBNoPadding}实现对{@link Properties}中指定的property值提供加密保护
* @author guyadong
*
*/
public class EncryptedProperties extends Properties {
private static final long serialVersionUID = 2102942876991337031L;
/**
* 密钥
*/
private final String password;
/**
* 需要保护的key集合
*/
private final LinkedHashSet protectedKeys = new LinkedHashSet<>();
/**
* 是否保护所有key
*/
private final boolean protecteAll;
/**
* 是否需要解密标志,用于控制{@link #get(Object)}对返回的值是否要解密,{@link #put(Object, Object)}对设置的值是否要加密,
*/
private boolean trans;
/**
* 构造方法
* @param properties 原始的{@link Properties}实例,如果不为{@code null},则全部将其中的property加入当前对象
* @param password 密钥,用于加密解密,为{@code null}或空时不实现加密保护
* @param protectedKeys 指定需要加密保护的key集合,为{@code null}或空对所有key加密保护
*/
public EncryptedProperties(Properties properties, String password, Iterable protectedKeys) {
this.password = password;
if(null != protectedKeys){
for(String protectedKey:protectedKeys){
if(null != protectedKey && protectedKey.length() > 0){
this.protectedKeys.add(protectedKey);
}
}
this.protecteAll = this.protectedKeys.isEmpty();
}else{
this.protecteAll = true;
}
if(null != properties){
putAll(properties);
}
// 要放到putAll后面,因为构造函数中putAll不需要对值加密
trans = true;
}
/**
* 构造方法
* @param password 密钥,用于加密解密,为{@code null}时不实现加密保护
* @param protectedKeys 指定需要加密保护的key集合,为{@code null}时不实现加密保护
*/
public EncryptedProperties(String password, Iterable protectedKeys) {
this(null, password, protectedKeys);
}
private EncryptedProperties(Builder builder) {
this(builder.properties,builder.password,builder.protectedKeys);
}
@Override
public String getProperty(String key) {
Object oval = get(key);
String sval = (oval instanceof String) ? (String)oval : null;
return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}
/**
* 如果指定的key为受保护的key则对返回值解密再返回
* @see java.util.Hashtable#get(java.lang.Object)
*/
@Override
public synchronized Object get(Object key) {
Object value = super.get(key);
if( trans && value instanceof String
&& password != null && password.length() > 0
&& (protecteAll || protectedKeys.contains(key))){
try {
return wrapDecrypt((String)value, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return value;
}
/**
* 如果指定的key为受保护的key则对要设置的值加密后再加入hashTable
* @see java.util.Hashtable#put(java.lang.Object, java.lang.Object)
*/
@Override
public synchronized Object put(Object key, Object value) {
if(trans && value instanceof String
&& password != null && password.length() > 0
&& (protecteAll || protectedKeys.contains(key))){
try {
value = wrapEncrypt((String)value, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return super.put(key, value);
}
@Override
public void store(Writer writer, String comments) throws IOException {
try {
trans = false;
super.store(writer, comments);
} finally {
trans = true;
}
}
@Override
public void store(OutputStream out, String comments) throws IOException {
try {
trans = false;
super.store(out, comments);
} finally {
trans = true;
}
}
@Override
public void storeToXML(OutputStream os, String comment) throws IOException {
try {
trans = false;
super.storeToXML(os, comment);
} finally {
trans = true;
}
}
@Override
public void storeToXML(OutputStream os, String comment, String encoding) throws IOException {
try {
trans = false;
super.storeToXML(os, comment, encoding);
} finally {
trans = true;
}
}
@Override
public synchronized void load(Reader reader) throws IOException {
try {
trans = false;
super.load(reader);
} finally {
trans = true;
}
}
@Override
public synchronized void load(InputStream inStream) throws IOException {
try {
trans = false;
super.load(inStream);
} finally {
trans = true;
}
}
@Override
public synchronized void loadFromXML(InputStream in) throws IOException, InvalidPropertiesFormatException {
try {
trans = false;
super.loadFromXML(in);
} finally {
trans = true;
}
}
@Override
public String toString() {
int max = size() - 1;
if (max == -1)
return "{}";
StringBuilder sb = new StringBuilder();
Iterator it = keySet().iterator();
sb.append('{');
for (int i = 0; ; i++) {
Object key = it.next();
Object value = get(key);
sb.append(key == this ? "(this Map)" : key.toString());
sb.append('=');
sb.append(value == this ? "(this Map)" : value.toString());
if (i == max)
return sb.append('}').toString();
sb.append(", ");
}
}
/**
* @return {@link Builder}实例
*/
public static Builder builder(){
return new Builder();
}
/**
* 将{@link Properties}封装为{@link EncryptedProperties}实例
* 如果{@code properties}已经是{@link EncryptedProperties}实例则直接返回
* @param properties
* @param password
* @param protectedKeys
* @return {@link EncryptedProperties}实例
* @see #EncryptedProperties(Properties, String, Iterable)
*/
public static EncryptedProperties wrap(Properties properties, String password, Iterable protectedKeys){
if(properties instanceof EncryptedProperties){
return (EncryptedProperties)properties;
}
return new EncryptedProperties(properties,password,protectedKeys);
}
public static class Builder{
private Properties properties = new Properties();
private String password;
private LinkedHashSet protectedKeys = new LinkedHashSet<>();
private Builder(){
}
/**
* @param properties 要设置的 properties
* @return 当前对象
*/
public Builder properties(Properties properties) {
if(null != properties){
this.properties = properties;
}
return this;
}
/**
* 设置密钥
* @param password
* @return 当前对象
*/
public Builder password(String password) {
this.password = password;
return this;
}
/**
* 指定要保护的key
* @param protectedKeys
* @return 当前对象
*/
public Builder protectedKeys(Iterable protectedKeys) {
if(null != protectedKeys){
for(String key : protectedKeys){
protectedKey(key);
}
}
return this;
}
/**
* 指定要保护的key
* @param protectedKeys
* @return 当前对象
*/
public Builder protectedKeys(String... protectedKeys) {
if(null != protectedKeys){
for(String key : protectedKeys){
protectedKey(key);
}
}
return this;
}
/**
* 指定要保护的key
* @param protectedKey
* @return 当前对象
*/
public Builder protectedKey(String protectedKey) {
if(null != protectedKey && protectedKey.length() > 0){
this.protectedKeys.add(protectedKey);
}
return this;
}
/**
* 设置保护所有key
* @return 当前对象
*/
public Builder protectedAll(){
protectedKeys.clear();
return this;
}
/**
* 根据当前对象提供的参数创建{@link EncryptedProperties}实例
*/
public EncryptedProperties build(){
return new EncryptedProperties(this);
}
public EncryptedProperties wrap(){
return EncryptedProperties.wrap(properties, password, protectedKeys);
}
}
}